为什么const lvalues与给定T&&amp ;;和const T&重载?

时间:2013-07-20 05:43:02

标签: c++ c++11 overloading universal-reference

此代码(可在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左值时首选模板?

1 个答案:

答案 0 :(得分:1)

当可以从多个声明生成相同的函数模板特化时,使用函数模板的部分排序消除声明的歧义,如C ++ 11标准§14.5.6.2部分排序中所述函数模板[temp.func.order]。编译器确定哪个模板最专业并且更喜欢它。

在您的示例中,const T&的{​​{1}}重载比f重载更专业。直观地,T&&可以推导为T&&可以的任何内容,但反之亦然,因此const T&更具体,因此其函数重载更专业。