0

Short question;

I don't get why this syntax exists:

template <int in>
void test(){
 std::cout << in << std::endl;
}

int main(){
 test<5>();
 return 0;
}

When you can do the same without templates:

void test(test in){
 std::cout << in << std::endl;
}

int main(){
 test(5);
 return 0;
}
Dan
  • 577
  • 1
  • 3
  • 9
  • whats the "partial specialization" here? – 463035818_is_not_an_ai Oct 02 '20 at 13:18
  • 2
    Essentially, one is for compile-time parameters, one is for runtime parameters. Those have two completely different use cases. – 0x5453 Oct 02 '20 at 13:20
  • I thought passing a direct type in template is called partial specialization? – Dan Oct 02 '20 at 13:22
  • 1
    @Dan Partial specialization is when you have a class with multiple template parameters, but then you create a "specialized" class where a subset of those template parameters are fixed. In this case the term is "non-type template parameters". – 0x5453 Oct 02 '20 at 13:25
  • @Dan depending on amount, and structure, of parameters expected/passed. – bipll Oct 02 '20 at 13:27
  • But why do templates allow for passing in direct types? (like int, float etc)? beside the Partial specialization case, are there other cases it's used for? – Dan Oct 02 '20 at 13:27
  • Dan, SO is not the correct forum to get acquainted with the basics of writing generic C++ code. It's ill-suited for tutoring. Did you you have chance to examine [the curated book list](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list)? – StoryTeller - Unslander Monica Oct 02 '20 at 13:29
  • @0x5453 "compile-time parameters, one is for runtime parameters", care to give an example? – Dan Oct 02 '20 at 13:31
  • I edited the title. You used incorrect terminology for the syntax, but I don't think that's relevant to your question. – cigien Oct 02 '20 at 13:40
  • @cigien it is relevant for the latest answer – 463035818_is_not_an_ai Oct 02 '20 at 13:41
  • @cigien I also didnt read the question as specifically asking for non-type parameters compared to type parameters. I allowed myself to rollback – 463035818_is_not_an_ai Oct 02 '20 at 13:42
  • @cigien well, I don't know. The question was more clear with your title, not sure how to fix – 463035818_is_not_an_ai Oct 02 '20 at 13:45
  • 1
    @idclev463035818 Actually, the question seems to be asking the difference between non-type template parameters vs runtime function arguments. But I'm not sure that's what the OP means, they should decide anyway :) – cigien Oct 02 '20 at 13:45

3 Answers3

1

How would you do this without templates?

template<std::size_t n> void f() {
    char buf[n];
}

Besides, passing values as arguments requires extra arguments, extra run-time overhead, not necessarily needed when you know a value is actually a compile-time constant. With classes, it would require an extra member, and an extra construction argument for a class which might otherwise be empty and trivial.

bipll
  • 11,747
  • 1
  • 18
  • 32
  • 3
    You are about to get comments from folks who have VLA extensions enabled – StoryTeller - Unslander Monica Oct 02 '20 at 13:30
  • @StoryTeller ... and are unable to realize VLA is not the only use-case here? – bipll Oct 02 '20 at 13:33
  • So when passing arguments with templates, it's counted as "inline" and no extra space on stack is created to pass the args? – Dan Oct 02 '20 at 13:33
  • @Dan you may regard this as an extra function defined for _each_ possible parameter value: `test0()`, `test1()`, etc., all nullary. – bipll Oct 02 '20 at 13:35
  • I see what you mean. – Dan Oct 02 '20 at 13:37
  • Would they have VLA extension enabled and comment if they saw the bigger picture? And if you have a bigger point, I suggest you make it explicitly. – StoryTeller - Unslander Monica Oct 02 '20 at 13:37
  • @StoryTeller-UnslanderMonica Could you tell me the relation between VLAs ( Variable-length arrays in C) and this answer? – Dan Oct 02 '20 at 14:35
  • @Dan - The key word in my comments is "extension". Two very popular compilers offer VLA's in C++ code as an extension. And the default mode when executing those compilers has extensions enabled. There are many questions posted on the [tag:c++] tag by people who encounter it and are unaware they are using an extension to C++ offered by their compiler. – StoryTeller - Unslander Monica Oct 02 '20 at 14:43
1

What you have shown is not partial specialization.

Here an example of specialization (in this case full specialization):

#include <iostream>

template <int in, int in2>
void test_template(){
    std::cout << in << std::endl;
}

template <>
void test_template<1>(){
    std::cout << "one" << std::endl;
}


template <>
void test_template<2>(){
    std::cout << "two" << std::endl;
}

int main()
{
    test_template<1>();
    test_template<2>();
    test_template<3>();
    test_template<4>();
}

And it is useful to handle certain template parameters in a special way. (Partial specialization, is if you have multiple template arguments and specialize all except one of them)

Regarding your example, the use-case you have shown does not illustrate where it can be useful, as it indeed does not make much a difference to use a regular function there.

But if you look at functions like std::make_shared or std::make_pair there is no way how you could solve that without using templates:

template< class T1, class T2 >
std::pair<T1,T2> make_pair(T1 t, T2 u) {
   return std::pair<T1,T2>(t,u);
}
t.niese
  • 39,256
  • 9
  • 74
  • 101
0

They are not "the same".

The two versions of test are very different. I rename them to avoid confusion and merely list some differences:

template <int in>
void test_template(){
    std::cout << in << std::endl;
}

void test_fun(test in){
    std::cout << in << std::endl;
}  

test_template is a template. It is not a function. For example it is not possible to get a pointer to test_template:

auto f_ptr1 = &test_template; // doesn't make sense
auto f_ptr2 = &test_fun;      // OK

The template parameter has to be known at compile time:

int x;
std::cin >> x;
test_template<x>();  // error: x must be known at compile time
test_fun(x);         // OK

On the other hand, once you did instantiate the template you get a function with no parameters:

auto f = &test_template<5>;
f();
auto g = &test_template<6>;
g();

Similar you can only do with test_fun when you wrap it into another function (ie overhead).

... and more.

PS: There is no partial specialization in your code.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185