12

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

#include <utility>

struct foo
{
};

int main()
{
    foo bar;

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

似乎隐式生成的赋值运算符 forfoo没有&引用限定,因此可以在右值上调用。根据标准,这是否正确?如果是这样,有什么理由要求隐式生成的赋值运算符被重新&限定?

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

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

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

2 回答 2

9

好吧,分配给右值有一些合法的用例。引用标准库中赋值运算符的 Ref-qualifiers:

只有少数非常具体的类型支持分配给右值是有意义的。特别是,用作代理的类型,例如vector<bool>::reference,以及赋值运算符是const 限定的类型(例如slice_array)。

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

诚然,要设计一个我们希望隐式声明的赋值运算符与右值一起使用的示例有点困难,但 C++ 标准委员会可能不想在保持向后兼容性方面冒险。像这样的代码:

int foo_counter = 0;

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

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

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

……再也行不通了。归根结底,标准委员会希望确保以前有效的 C++(无论多么愚蠢或做作)继续在 C++11 中工作。

于 2013-06-08T02:53:02.547 回答
2

您的问题似乎更多的是“为什么分配给右值有用? ”而不是“为什么标准的 ref 限定自动生成的构造函数?

允许分配给右值的原因是因为在某些情况下它很有用。

一个示例用法是 with 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 借来的示例然后修改

于 2013-06-08T02:57:42.653 回答