7

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

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

4

2 回答 2

6

is_assignable<T,U>为真,如果:

表达式declval<T>() = declval<U>()格式正确

declval<T>被声明为返回对 的引用的函数T

template <class T>
  typename add_rvalue_reference<T>::type declval() noexcept;

whereadd_rvalue_reference<T>::type右值引用类型 ( T&&) 如果T是对象或函数类型,或者T本身是引用类型。

这意味着只有当它是非常量左值引用类型is_assignable<T,U>时才为真。如果是对象类型,则为右值引用类型;所以表达式是一个xvalue,不能分配给它。Tadd_rvalue_reference<T>::typedeclval<T>()

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

于 2012-12-19T15:39:31.207 回答
3

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

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

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

所以我说 GCC 就在这里。

于 2012-12-19T15:40:10.503 回答