_Remove_reference exists for, as you know, converting T& to T or T&& to T.
I made the following code in a playful mood, it doesn't work at all as I expected, but have no idea why.
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;
}
I guess it's all about reference collapsing rules, and template argument deduction but I am confused. my curiosity about this has to be shattered for me to sleep tight.
Thanks in advance.
Given
template<class _Ty> inline
typename _Remove_reference<_Ty>::_Type&&
move(_Ty&& _Arg)
When you do move(a1)
, _Ty
is deduced as int&
. _Ty&&
would thus still be int&
due to the reference collapsing rules, so you need to remove the reference to get int
before you can make it an rvalue reference.
This is a special case of the template argument deduction rules. If you have a function argument which is T&&
where T
is a template parameter, then if you pass an lvalue (i.e. a named object or an lvalue reference) to the function then T
is deduced as X&
where X
is the type of the lvalue object. If you pass an rvalue (a temporary or an rvalue reference) to the function then T
is just deduced as X
.
e.g. move(a1)
deduces _Ty
to be int&
, whereas move(42)
deduces _Ty
to be int
.
BTW: I guess you took this code from your compiler's standard library --- names decorated with a leading underscore and a capital letter _Like _This are reserved for the compiler and standard library implementation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With