How to derive a template parameter in an explicit specialization of a function template?

Consider the following case:

#include <iostream> template <class T> void f(T) { std::cout << "#1\n"; } // #1 template <> void f(const int) { std::cout << "#2\n"; } // #2 int main() { f<const int>(1); // call #1 f<int>(1); // call #2 return 0; } 

It seems that # 2 is f<int>(const int) instead of f<const int>(const int) . What's going on here? My first thought was that the upper level const discarded in the type conversion of the function, so that type # 2 is void(int) , which leads to the specialization f<int>(const int) . But I'm not so sure about that.

And why does C ++ allow such syntax? I mean, since we cannot partially specialize function templates, we would know the value of the template argument if we want to explicitly highlight it. So why does C ++ not just force the programmer to explicitly provide the values โ€‹โ€‹of the template arguments when specializing the template functions? (i.e. we would have to write specialization No. 1 in template <> void f<int>(const int) { } or template <> void f<int const>(const int) { } ) Does it have special use, other than coding convenience?

+6
source share
1 answer
 void f(const int p) 

Having cast aside the question about templates, at the moment the const part here does not indicate the type of the f() parameter. Here, everything const indicates that p is const inside the function f() . The parameter type f() is int .

 template <> void f(const int) 

When the compiler tries to infer the type of specialization, it infers that, since the parameter type of the function is int , it must be a specialization for f<int> .

It is impossible to truly do deduction work. You must be explicit if this is what you want to do:

 template <> void f<const int>(const int) { std::cout << "#2\n"; } 
+6
source

All Articles