2

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

環境: Linux、g++-4.7

これをテストするために、std::vector と独自のクラスを使用しました。そして、std::initializer_list を使用してベクターを構築する場合、実際にはカスタム クラスのコピー コンストラクターを呼び出して一時オブジェクトを作成することがわかりました。したがって、私はそれを非常に効率的ではないと考え、「const std::initializer_list & li」を使用して置き換えました。

STLライブラリで本当に一般的なのはなぜですか?? 例えば:

// This is in STL: stl_vector.h
vector(initializer_list<value_type> __l, const allocator_type & __a = allocator_type())
//...

実際に私の心をスキップしたものはありますか?

私のテストコードを以下に示します。

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

class Test
{
public:
    Test(const Test & t) : v(t.v) {
        std::cout << "Copy Cons" << std::endl;
    }
    Test(Test && t) : v(std::move(t.v)) {
        std::cout << "MC" << std::endl;
    }
    Test(int val) : v(val) {}
private:
    int v;
};

int main()
{
    std::vector<Test> vv({Test(0), Test(1), Test(2)});

    return 0;
}//main

それは出力です:

Copy Cons
Copy Cons
Copy Cons
4

1 に答える 1

3

最初のコメントで提供されたリンクをよく見ると、コピーが発生する理由がわかります。

  1. initializer_list を定義すると、コンパイラはそのリストの内容をメモリのチャンクのどこかに詰め込みます。この場合、initializer_list は、そのメモリ チャンクの開始点と終了点を指す 2 つのポインターのみで構成されます。
  2. リストがコンストラクターにコピーされると、ポインターのみがコピーされます。
  3. ベクターが独自のメモリを割り当てると、オブジェクトをリストのチャンク 'o'mem から独自のメモリにコピーします。リスト自体がコピーされたときではなく、そこにコピー ctor が表示されます。

初期化子 lis という名前の構文要素、つまり中括弧とコンマ区切りの値のリストは、コンパイラがそのリストの内容を読み取り専用のメモリ チャンクに配置するための命令です。はstd::initializer_list、そのチャンクに対するイテレータのペアにすぎません。

于 2012-11-28T12:56:37.347 に答える