【问题标题】:Inconsistent results of is_assignable<> [duplicate]is_assignable<> 的结果不一致 [重复]
【发布时间】:2012-12-19 15:29:33
【问题描述】:

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

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

【问题讨论】:

    标签: c++


    【解决方案1】:

    is_assignable&lt;T,U&gt; 为真,如果:

    表达式declval&lt;T&gt;() = declval&lt;U&gt;() 格式正确

    declval&lt;T&gt; 被声明为返回对T 的引用的函数:

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

    如果T 是对象或函数类型,则add_rvalue_reference&lt;T&gt;::type右值 引用类型(T&amp;&amp;),如果是引用类型,则T 本身。

    这意味着is_assignable&lt;T,U&gt; 只能在T 是非常量左值 引用类型时为真。如果是对象类型,那么add_rvalue_reference&lt;T&gt;::type是一个右值引用类型;所以表达式declval&lt;T&gt;() 是一个xvalue,不能赋值。

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

    【讨论】:

    • 是的,这是一件可悲且具有误导性的事情,我敢打赌最初的意图是不同的,但现在是这样。我也曾为此而堕落,并写下了我自己的可分配特征。
    • 或许应该重命名为is_assignable_lvalue_reference&lt;T,U&gt;。 =/
    【解决方案2】:

    is_assignable&lt;T,U&gt;::value 定义为真,当declval&lt;T&gt;() = declval&lt;U&gt;() 格式正确且declval&lt;T&gt; 定义为返回add_rvalue_reference&lt;T&gt;::type 的函数。

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

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

    所以每种情况:

    1. is_assignable&lt;int, int&gt;is_assignable&lt;int, char&gt;

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

    2. std::is_assignable&lt;int&amp;, int&gt;std::is_assignable&lt;int&amp;, char&gt;

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

    3. std::is_assignable&lt;int, int&amp;&gt;std::is_assignable&lt;int, char&amp;&gt;

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

    所以我说 GCC 就在这里。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-11
      • 1970-01-01
      • 1970-01-01
      • 2014-09-21
      • 2021-11-29
      • 2018-10-31
      • 2021-03-27
      • 2021-07-03
      相关资源
      最近更新 更多