5

正しく理解できれば、移動セマンティクスにより、一時的な名前のないオブジェクトからリソースを移動して再利用できます。RVO では、先行するムーブ セマンティクスはさらに進んで、オブジェクト全体を「盗み」、余分なコンストラクターの呼び出しと代入/コピー機能を回避します。

呼び出されたコンストラクターが最終的な左辺値ターゲットのアドレスを直接使用して、ユーザーが必要とする場所にデータを直接配置する場合、これは私には少し直感的ではありませんか?

つまり、「このオブジェクトをこの場所に作成する」は、「このオブジェクトをどこかに作成してから、適切な場所にコピーする」よりも少し直感的に思えます。

4

1 に答える 1

7

はい、それは「少し直感に反する」です。コピー省略を有効にすると、コンストラクターのすべての副作用も省略されます。

#include <iostream>

struct X {
    X() { std::cout << "Construct" << std::endl; }
    X(X&&) { std::cout << "Move" << std::endl; }
    ~X() { std::cout << "Destruct" << std::endl; };
};

X f() { return X(); }

int main()
{
    X x(f());
    return 0;
}

コピー省略: g++ -std=c++11 src-test/main.cc

Construct
Destruct

コピー省略なし: g++ -std=c++11 -fno-elide-constructors src-test/main.cc

Construct
Move
Destruct
Move
Destruct
Destruct

コンパイラは、プログラム/ライブラリがビルドされるハードウェアを認識しており、(オプションで) コピー省略を適用できます。C++ 言語自体は、ハードウェア固有の戻りメカニズムを認識していません。したがって、このコンテキストで特定のアドレスに構築することはできません。

于 2013-12-17T12:43:52.163 に答える