正确:
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);
}
我不明白这些模板函数如何实例化之间的区别。两种函数的返回类型有何不同?
答案 0 :(得分:3)
这是reference collapsing rules of C++11。
的结果如果您的类型为T &&
:
T
为U
,则会获得U &&
。T
为U &
,那么您会获得U & &&
,这会折叠为U &
。T
为U &&
,那么您会获得U && &&
,这会折叠为U &&
。 std::remove_reference
将&#34;删除&#34;来自类型的左值引用或右值引用,导致T &
和T &&
变为T
。
因此,当您的T
为U &
时,返回类型不同:
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
所需的。