为什么输出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) ;
}
是
一般
一般
一般
第三个是令人惊讶的,因为该功能专门针对int&
编辑:我知道重载可能是一个合适的解决方案。我只是想了解它背后的逻辑。
答案 0 :(得分:9)
表达式y
和表达式z
的类型均为int
。表达式中出现的引用不会保留引用类型。相反,表达式的类型将是引用的类型,表达式是左值。
因此,在这两种情况下,T
都推导为int
,因此根本不使用显式特化。
重要的是要注意(除了你应该真的使用重载,正如另一个人所说),你的模板中有一个非参考函数参数。在对参数类型进行任何推导T
之前,参数类型将从数组转换为指向其第一个元素的指针(对于函数,参数将转换为函数指针)。因此,具有非参考函数参数的函数模板无论如何都不允许精确推导。
答案 1 :(得分:1)
引用只是一个别名,而不是一个类型。所以当你调用f(z)时,它匹配第一个版本的T = int,这是一个更好的选择,T = int&amp;。如果你把T改为T&amp;,那么int和int&amp;参数将调用第二个版本。
答案 2 :(得分:0)
我知道这不是答案,但恕我直言,你可以试试这个,在结构中采用类似特征的方法:
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 ;}
};