is_assignable<>的结果不一致

时间:2012-12-19 15:29:33

标签: c++

  

可能重复:
  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

根据标准,哪个结果是正确的?

2 个答案:

答案 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&&

所以每个案例:

  1. is_assignable<int, int>is_assignable<int, char>

    我们可以将返回右值引用(xvalue)的函数的结果赋给另一个返回右值引用(另一个xvalue)的函数的结果。不,我们不能。这应该是false

  2. std::is_assignable<int&, int>std::is_assignable<int&, char>

    我们可以将函数的结果赋值给返回左值引用(左值)的函数返回一个右值引用(一个xvalue)。我们当然可以。这应该是true

  3. std::is_assignable<int, int&>std::is_assignable<int, char&>

    我们可以将函数的结果赋值给返回左值引用(xvalue)的函数返回左值引用(左值)。不,我们不能。这应该是false

  4. 所以我说海湾合作委员会就在这里。