is_assignable<>结果不一致

Inconsistent results of is_assignable<>

本文关键字:gt 结果 不一致 lt assignable is      更新时间:2023-10-16

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

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

>如果为真,则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右值引用类型(T&&如果它是对象或函数类型),则T是右值引用类型,如果是引用类型,则T本身。

这意味着,仅当T是非常量左值引用类型时,is_assignable<T,U>才能为 true。如果是对象类型,则add_rvalue_reference<T>::type右值引用类型;因此,表达式declval<T>()是一个x值,不能分配给它。

所以,除非我误读了标准,否则GCC是正确的,VS2012是错误的。即使is_assignable<int,int>为真似乎更有意义,但事实并非如此。

declval<T>() = declval<U>()格式正确且declval<T>定义为返回add_rvalue_reference<T>::type的函数时,is_assignable<T,U>::value定义为true。

我们必须记住,赋值仅对可修改的左操作数有效。还要记住参考折叠的规则(尤其是最后两个):

T&  &  -> T&
T&& &  -> T&
T&  && -> T&
T&& && -> T&&

所以每种情况:

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

    我们可以将返回右值引用(x值)的函数的结果分配给另一个返回右值引用(另一个 x值)的函数的结果吗?不,我们不能。这应该是false.

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

    我们是否可以将返回右值引用(x值)的函数的结果分配给返回左值引用(左值)的函数的结果。我们当然可以。这应该是true.

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

    我们是否可以将返回左值引用(左值)的函数的结果分配给返回右值引用(x值)的函数的结果。不,我们不能。这应该是false.

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