_Remove_reference存在于转换T&到T或T&&到T。
我以一种俏皮的心情制作了以下代码,它根本不符合我的预期,但不知道为什么。
template<class _Ty>
struct _Remove_reference
{ // remove reference
typedef _Ty _Type;
static void func(){ cout << "1" << endl; }
};
// template<class _Ty>
// struct _Remove_reference<_Ty&>
// { // remove reference
// typedef _Ty _Type;
// static void func(){ cout << "2" << endl; }
// };
//
// template<class _Ty>
// struct _Remove_reference<_Ty&&>
// { // remove rvalue reference
// typedef _Ty _Type;
// static void func(){ cout << "3" << endl; }
// };
template<class _Ty> inline
typename _Remove_reference<_Ty>::_Type&&
move(_Ty&& _Arg)
{ // forward _Arg as movable
typename _Remove_reference<_Ty>::func();
return ((typename _Remove_reference<_Ty>::_Type&&)_Arg);
}
int main(){
int a1= 3;
int&& a2 = move(a1); // can't convert the a1 to int&&
return 0;
}
我想这都是关于参考折叠规则和模板参数推导但我很困惑。我对此的好奇心必须让我睡不着觉。
提前致谢。
答案 0 :(得分:8)
鉴于
template<class _Ty> inline
typename _Remove_reference<_Ty>::_Type&&
move(_Ty&& _Arg)
当您执行move(a1)
时,_Ty
被推断为int&
。由于参考折叠规则,_Ty&&
因此仍然是int&
,因此您需要删除引用以获取int
,然后才能使其成为右值参考。
这是模板参数推导规则的特例。如果你有一个T&&
函数参数,其中T
是一个模板参数,那么如果你将一个左值(即命名对象或左值引用)传递给函数,那么T
是推导为X&
,其中X
是左值对象的类型。如果您将rvalue(临时或右值引用)传递给函数,则T
只是推导为X
。
e.g。 move(a1)
将_Ty
推断为int&
,而move(42)
推导_Ty
为int
。