Possible Duplicate:
What is the difference between is_convertible is_assignable
I use this test code:
cout<<std::is_assignable<int, int>::value<<endl;
cout<<std::is_assignable<int, char>::value<<endl;
cout<<std::is_assignable<int&, int>::value<<endl;
cout<<std::is_assignable<int&, char>::value<<endl;
cout<<std::is_assignable<int, int&>::value<<endl;
cout<<std::is_assignable<int, char&>::value<<endl;
The result in vs2012 is:
true
true
true
true
true
true
In gcc4.7.2 I get:
false
false
true
true
false
false
Which result is correct according to the standard?
is_assignable<T,U>
is true if:
The expression
declval<T>() = declval<U>()
is well-formed
declval<T>
is declared as a function returning a reference to T
:
template <class T>
typename add_rvalue_reference<T>::type declval() noexcept;
where add_rvalue_reference<T>::type
is an rvalue reference type (T&&
) if T
is an object or function type, or T
itself if it is a reference type.
This means that is_assignable<T,U>
can only be true if T
is a non-const lvalue reference type. If it's an object type, then add_rvalue_reference<T>::type
is an rvalue reference type; so the expression declval<T>()
is an xvalue, which cannot be assigned to.
So, unless I've misread the standard, GCC is correct and VS2012 is wrong. Even if it might seem to make more sense for is_assignable<int,int>
to be true, it is not.
is_assignable<T,U>::value
is defined as true when declval<T>() = declval<U>()
is well-formed and declval<T>
is defined as a function returning add_rvalue_reference<T>::type
.
We must remember that an assignment is only valid for a modifiable lvalue as the left operand. Also remember the rules of reference collapsing (especially the last two):
T& & -> T&
T&& & -> T&
T& && -> T&
T&& && -> T&&
So each case:
is_assignable<int, int>
and is_assignable<int, char>
Can we assign the result of a function returning an rvalue reference (an xvalue) to the result of another function returning an rvalue reference (another xvalue). No we can't. This should be false
.
std::is_assignable<int&, int>
and std::is_assignable<int&, char>
Can we assign the result of a function returning an rvalue reference (an xvalue) to the result of a function returning an lvalue reference (an lvalue). We sure can. This should be true
.
std::is_assignable<int, int&>
and std::is_assignable<int, char&>
Can we assign the result of a function returning an lvalue reference (an lvalue) to the result of a function returning an rvalue reference (an xvalue). No we can't. This should be false
.
So I say GCC is right here.
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