在c ++中实例化模板

时间:2015-01-22 10:16:22

标签: c++ templates

正确:

template<typename T>
typename remove_reference<T>::type&& move(T&&d){
  return static_cast<typename remove_reference<T>::type&&>(d);
}

错:

template<typename T>
T&& move(T&&d){
  return static_cast<typename remove_reference<T>::type&&>(d);
}

我不明白这些模板函数如何实例化之间的区别。两种函数的返回类型有何不同?

2 个答案:

答案 0 :(得分:3)

这是reference collapsing rules of C++11

的结果

如果您的类型为T &&

  • 如果TU,则会获得U &&
  • 如果TU &,那么您会获得U & &&,这会折叠为U &
  • 如果TU &&,那么您会获得U && &&,这会折叠为U &&

std::remove_reference将&#34;删除&#34;来自类型的左值引用或右值引用,导致T &T &&变为T

因此,当您的TU &时,返回类型不同:

  • 您的第一个示例返回U & &&,这真的是U & - 完全不是我们希望std::move()返回的内容!
  • 您的第二个示例返回U &&

答案 1 :(得分:2)

您需要考虑当您使用不同类型调用第二个版本时会发生什么,引用折叠将导致以下内容:

int a{};
move(a); // return type deduced as int& &&, i.e. int&
move(1); // return type deduced as int&& &&, i.e. int&&

第一个版本将始终生成右值引用类型,这是move所需的。