简体   繁体   中英

non-type template parameters, partial specialization vs function argument in C++

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;
}

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.

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);
}

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM