此代码(可在http://ideone.com/Mo7fQr获得)
template<typename T>
void f(const T&) { std::cout << "const T& overload\n"; }
template<typename T>
void f(T&&) { std::cout << "T&& overload\n"; }
int main()
{
const int x = 0;
f(x); // calls const T& overload
f(std::move(x)); // calls T&& overload
}
第一次调用f
(带左值)调用const T&
重载,而第二次调用(带右值)调用T&&
重载。至少gcc 4.8.1和最新的VC ++(VC12)会发生这种情况。
我想我理解为什么第二个调用会解析它:因为第一个模板实例化为采用const int&
参数,而第二个模板实例化为采用const int&&
参数,并且因为参数在调用站点传递的是一个右值,它优先绑定到右值引用。 (我相信这是在C ++ 11标准13.3.3.2/3 bullet 1子弹4中指定的。)
但是对于f
的第一次调用,两个模板都实例化为采用const int&
类型的参数。那么,为什么在传递const
左值时首选模板?
答案 0 :(得分:1)
当可以从多个声明生成相同的函数模板特化时,使用函数模板的部分排序消除声明的歧义,如C ++ 11标准§14.5.6.2部分排序中所述函数模板[temp.func.order]。编译器确定哪个模板最专业并且更喜欢它。
在您的示例中,const T&
的{{1}}重载比f
重载更专业。直观地,T&&
可以推导为T&&
可以的任何内容,但反之亦然,因此const T&
更具体,因此其函数重载更专业。