1

对于此代码(可在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 sub-bullet 4 中指定的。)

但是对于第一次调用f,两个模板都实例化为采用类型参数const int&const那么为什么传入左值时首选第一个模板呢?

4

1 回答 1

1

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

在您的示例中,const T&重载的f比重载更专业T&&。直观地说,T&&可以推导出任何const T&可以,但反之亦然,所以const T&更具体,因此它的函数重载更专业。

于 2013-07-20T07:37:51.130 回答