1

重複の可能性:
initializer_list および move セマンティクス

次の例では、一時オブジェクトが送信されても​​最終的にコピーが実行されます。

// test.cpp

#include <iostream>
#include <vector>
#include <utility>
#include <initializer_list>

using namespace std;

class mystr : public string
{
public:
    mystr() = default;
    mystr(const char* c) : string(c) { }

    mystr(mystr& m) : string(m) { cout << "& " << c_str() << endl; }
    mystr(mystr const & m) : string(m) { cout << "const & " << c_str() << endl; }
    mystr(mystr&& m) : string(move(m)) { cout << "&& " << c_str() << endl; }
};

class myvector
{
public:
    myvector(initializer_list<mystr> i)
    {
        cout << "Inside constructor" << endl;

        v = vector<mystr>(i);
    }

private:
    vector<mystr> v;
};

int main()
{
    mystr a("hello");

    myvector v{ a, mystr("bye"), a, mystr("sorry") };
}

出力:

$ g++ --version | grep "g++"
g++ (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2
$ g++ -std=c++11 test.cpp
$ ./a.out
& hello
& hello
Inside constructor
const & hello
const & bye
const & hello
const & sorry

「名前付き」オブジェクトはコピーされ、一時オブジェクトは省略されますが、イニシャライザ リストが構築されると、すべての要素が別の機会にコピーされます。イニシャライザ リストは、オブジェクトの元の性質に関する情報を消去しています。プロセスを使用-fno-elide-constructorsすると、より理解しやすくなります。

$ g++ -std=c++11 -fno-elide-constructors test.cpp
$ ./a.out
& hello
&& hello
&& bye
&& bye
& hello
&& hello
&& sorry
&& sorry
Inside constructor
const & hello
const & bye
const & hello
const & sorry

一時オブジェクトは 2 回移動され、永続オブジェクトはコンストラクターに到達する前に、つまりイニシャライザー リストを作成するプロセスでコピーおよび移動されます。コンストラクターに入ると、リスト内のすべてのオブジェクトはコンストラクターの観点からは永続的であるため、それらはすべてコピーされます。

この動作 (転送) を回避することは可能ですか?

イニシャライザリストが構築されるときにオブジェクトがすでに一度コピーされているため、コンテナは常にオブジェクトをイニシャライザリストから独自のコンテナに移動する必要があります(コピーしないでください)。なぜ 2 回連続してコピーするのですか?

4

0 に答える 0