隐式生成的赋值运算符应该是&裁判资格?

时间:2013-06-08 02:34:51

标签: c++ c++11 assignment-operator rvalue-reference rvalue

以下代码在gcc 4.8.1上编译没有问题:

#include <utility>

struct foo
{
};

int main()
{
    foo bar;

    foo() = bar;
    foo() = std::move( bar );
}

foo隐式生成的赋值运算符似乎不是& ref-qualified,因此可以在rvalues上调用。根据标准,这是正确的吗?如果是这样,那么要求隐式生成的赋值运算符为& ref-qualified的原因是什么?

为什么标准不要求生成以下内容?

struct foo
{
  foo & operator=( foo const & ) &;

  foo & operator=( foo && ) &;
};

2 个答案:

答案 0 :(得分:7)

嗯,有一些合法的用例可以用于分配rvalue。引用Ref-qualifiers for assignment operators in the Standard Library:

  

只有少数非常具体的类型才有意义   支持分配右值。特别是,作为一个类型的类型   代理,例如,vector&lt; bool&gt; :: reference,以及其赋值的类型   运算符是const限定的(例如,slice_array)。

C ++标准委员会显然认为默认赋值不应该有隐式ref限定符 - 而应该显式声明。实际上,如果突然所有隐式声明的赋值运算符都不能与rvalues一起使用,可能会有现有的代码停止工作。

当然,设想一个我们希望隐式声明的赋值运算符与rvalues一起工作的例子有点难,但C ++标准委员会可能不希望在保留向后兼容性时采取这种机会。像这样的代码:

int foo_counter = 0;

struct Foo
{
    Foo()
    {
        ++foo_counter;
    }

    ~Foo()
    {
        --foo_counter;
    }
};

int main()
{
    Foo() = Foo();
}

......不再适用了。在一天结束时,标准委员会希望确保以前有效的C ++(无论多么愚蠢或做作)继续在C ++ 11中工作。

答案 1 :(得分:2)

似乎你的问题更多&#34; 为什么分配给rvalue会有用?&#34;而不是&#34; 为什么没有标准的参考资格自动生成的构造函数?&#34;

允许赋予rvalue的原因是因为在某些情况下它是有用的。

一个示例用法是使用std::tie (link)

#include <set>
#include <tuple>

int main()
{
    std::set<int> s;

    std::set<int>::iterator iter;
    bool inserted;

    // unpacks the return value of insert into iter and inserted
    std::tie(iter, inserted) = s.insert(7);
}

从cppreference.com借来的示例然后修改了