Why is the output of this code :
#include <iostream>
template<typename T> void f(T param)
{
std::cout << "General" << std::endl ;
}
template<> void f(int& param)
{
std::cout << "int&" << std::endl ;
}
int main()
{
float x ; f开发者_如何学编程 (x) ;
int y ; f (y) ;
int& z = y ; f (z) ;
}
is
General
General General
The third one is surprizing because the function was specialized exactly for int&
Edit : I know that overloading might be a proper solution. I just want to learn the logic behind it.
The type of both the expression y
and the expression z
is int
. A reference appearing in an expression won't keep reference type. Instead, the type of the expression will be the referenced type, with the expression being an lvalue.
So in both cases, T
is deduced to int
, and thus the explicit specialization is not used at all.
What's important to note (other than that you should really use overloading, as another guy said), is that you have a non-reference function parameter in your template. Before any deduction of T
against the argument type is done, the argument type will be converted from arrays to a pointer to their first element (for functions, arguments will be converted to function pointers). So a function template with a non-reference function parameter doesn't allow for accurate deduction anyway.
A reference is just an alias, not a type. So when you call f(z), it matches the first version with T=int, which is a better option that T=int&. If you change T to T&, then both int and int& arguments will call the second version.
I know it is not answer but, IMHO you can try this, with a trait like approach in a struct:
template<typename T>
struct value_traits
{
static void print(){std::cout << "General" << std::endl ;}
};
template<>
struct value_traits<const long>
{
static void print(){std::cout << "const long" << std::endl ;}
};
template<>
struct value_traits<std::vector<unsigned char> >
{
static void print(){std::cout << "std::vector<unsigned char>" << std::endl ; }
};
template<>
struct value_traits<const int>
{
static void print(){std::cout << "const int" << std::endl ;}
};
精彩评论