14

ページ上方法: Move コンストラクターを作成するMicrosoft には、Move コンストラクターの作成方法の例があります。基本的には次の形式です。

MyClass::MyClass(MyClass&& lhs)
{
    *this = std::move(lhs);
}

私は試してみstd::moveましたが、ここで本当に必要ですが、なぜですか? move は に変換するだけだと思っていましたT&&。しかしlhs、すでにタイプMyClass&&ですよね?

4

1 に答える 1

20

名前付き右辺値参照は左辺値です。名前のない右辺値参照は右辺値です。これは、以下で std::move 呼び出しが必要な理由を理解するために重要です。foo&& r = foo(); foo f = std::move(r);

この回答を見てください: https://stackoverflow.com/a/5481588/1394283非常によく説明されています。


この関数を見てください:

void foo(X&& x)
{
  X anotherX = x;
  // ...
}

興味深い質問は、Xのコピー コンストラクターのどのオーバーロードが の本体で呼び出されるのfooかということです。ここでxは、右辺値参照として宣言されている変数です。xしたがって、それ自体も右辺値のようにバインドする必要がある、つまり X(X&& rhs);呼び出される必要があると期待するのはかなり妥当です。

次のように、移動セマティクスを名前のあるものに暗黙的に適用できるようにする

X anotherX = x;
// x is still in scope!

移動したばかりのもの、つまり盗んだばかりのものは、後続のコード行で引き続きアクセスできるため、危険なほど混乱し、エラーが発生しやすくなります。しかし、移動セマンティクスの全体的なポイントは、それが「重要ではない」場合にのみ適用することでした。つまり、移動元のものが移動した直後に死んで消えるという意味です。

そのため、右辺値参照の設計者は、それよりも少し巧妙な解決策を選択しました。

右辺値参照として宣言されるものは、左辺値または右辺値にすることができます。識別基準は次のとおりです。名前がある場合、それは左辺値です。それ以外の場合は右辺値です。

ソース: http://thbecker.net/articles/rvalue_references/section_05.html

于 2013-07-30T14:17:26.777 に答える