可能重复:
What is the difference between is_convertible is_assignable
我使用此测试代码:
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;
vs2012的结果是:
true
true
true
true
true
true
在gcc4.7.2中我得到:
false
false
true
true
false
false
根据标准,哪个结果是正确的?
答案 0 :(得分:6)
is_assignable<T,U>
为真。
表达式
declval<T>() = declval<U>()
格式正确
declval<T>
被声明为返回对T
的引用的函数:
template <class T>
typename add_rvalue_reference<T>::type declval() noexcept;
其中add_rvalue_reference<T>::type
是 rvalue 引用类型(T&&
),如果T
是对象或函数类型,或T
本身,如果它是一种参考类型。
这意味着is_assignable<T,U>
只有在T
是非const 左值引用类型时才能为真。如果它是对象类型,则add_rvalue_reference<T>::type
是 rvalue 引用类型;所以表达式declval<T>()
是 xvalue ,无法分配给它。
所以,除非我误读标准,否则GCC是正确的,VS2012是错误的。即使is_assignable<int,int>
似乎更有意义,但事实并非如此。
答案 1 :(得分:3)
is_assignable<T,U>::value
格式正确且declval<T>() = declval<U>()
被定义为返回declval<T>
的函数时, add_rvalue_reference<T>::type
被定义为true。
我们必须记住,赋值仅对可修改的左值作为左操作数有效。还要记住参考折叠规则(特别是最后两个):
T& & -> T&
T&& & -> T&
T& && -> T&
T&& && -> T&&
所以每个案例:
is_assignable<int, int>
和is_assignable<int, char>
我们可以将返回右值引用(xvalue)的函数的结果赋给另一个返回右值引用(另一个xvalue)的函数的结果。不,我们不能。这应该是false
。
std::is_assignable<int&, int>
和std::is_assignable<int&, char>
我们可以将函数的结果赋值给返回左值引用(左值)的函数返回一个右值引用(一个xvalue)。我们当然可以。这应该是true
。
std::is_assignable<int, int&>
和std::is_assignable<int, char&>
我们可以将函数的结果赋值给返回左值引用(xvalue)的函数返回左值引用(左值)。不,我们不能。这应该是false
。
所以我说海湾合作委员会就在这里。