12

次のコードは、gcc 4.8.1 で問題なくコンパイルされます。

#include <utility>

struct foo
{
};

int main()
{
    foo bar;

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

暗黙的に生成された代入演算子は参照修飾されfooていない&ため、右辺値で呼び出すことができるようです。これは標準に従って正しいですか?もしそうなら、暗黙的に生成された代入演算子を参照修飾する必要がない理由は何ですか?&

標準では、以下を生成する必要がないのはなぜですか?

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

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

2 に答える 2

9

まあ、右辺値に代入する正当なユースケースがいくつかあります。標準ライブラリの代入演算子の参照修飾子から引用するには:

右辺値への代入をサポートすることが理にかなっている、非常に特殊な型はごくわずかです。特に、プロキシとして機能する型 (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-qualify自動生成コンストラクターを使用しないのですか? 」ではなく、「右辺値への割り当てが役立つのはなぜですか? 」のようです。

右辺値への割り当てが許可される理由は、それが役立つ場合があるためです。

使用例の 1 つは、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 に答える