4

STL コンテナーを返す関数がある場合、標準コンテナーの内容全体のコピーが発生しますか?

例:

void Foo( std::vector< std::string >* string_list );

これより良い:

std::vector< std::string > Foo();

容器に何が入っているかは重要ですか?たとえば、次のようなコンテナーを返します。

struct buzz {
    int a;
    char b;
    float c;
}

std::map< int, buzz > Foo();

これよりもコストのかかる操作になります。

std::map< int, int > Foo();

ありがとう、ポールH


編集: これはC ++ 03を使用しています。残念ながら、C++0x ソリューションは受け入れられません。

Edit2: Microsoft Visual Studio 2008 コンパイラを使用しています。

4

5 に答える 5

6

C++03 はおそらく (命名された) 戻り値の最適化 (google RVO および NRVO) を行うでしょう。

その最適化が適用できない場合、C++0x はムーブ セマンティクスを実行します。

于 2011-02-17T21:08:33.480 に答える
3

私は100%確信が持てませんでしたが、いいえ(コメンテーターに感謝します):

#include <vector>
#include <iostream>

#define LOCAL_FUN

struct A {
    A() { std::cout << "default ctor" << std::endl; }
    A(const A &a) { std::cout << "copy ctor" << std::endl; }
};

#ifdef LOCAL_FUN
std::vector<A> *pVec = NULL;
#endif

std::vector<A> func()
{
    std::vector<A> vec;
#ifdef LOCAL_FUN
    pVec = &vec;
#endif
    vec.push_back(A());
    std::cout << "returning" << std::endl;
    return vec;
}

int main(int argc, char *argv[])
{
    std::vector<A> ret = func();
#ifdef LOCAL_FUN
    if (pVec) {
        std::cout << pVec->size();
    }
#endif
}

出力 (LOCAL_FUN を使用):

default ctor
copy ctor
returning
1

編集: コードをいじってみると、ローカル変数 (LOCAL_FUN) を楽しく使うことができました。したがって、コピーを最適化しない非常に悪いコンパイラは、実際にこのコードを壊す可能性があります...

于 2011-02-17T21:12:35.603 に答える
2

はい、コンテナのコピーが含まれますが、使用しないでくださいvoid Foo( std::vector< std::string >* string_list );void foo( vector<string>& string_list);代わりに使用してください。

または、C++0x に切り替えて、ライブラリに実装されている最適化を既に実行しているコンパイラを使用します。

于 2011-02-17T21:08:43.467 に答える
0

コンテナーのコピー コンストラクターに依存します。C++ には値渡しのセマンティクスがあります。したがって、関数 Foo() のベクトルを返す場合、値のセマンティクスを使用して返されます。つまり、ベクトルの値をコピーするためにコピー コンストラクターが呼び出されます。この場合、std::vector のコピー コンストラクターは新しいコンテナーを作成し、値をコピーします。コンテナーにポインターを渡す場合、まだ割り当てていない場合はメモリを割り当てる必要があるため、ポインターは null 値ではなく実際のコンテナーを指します。プログラミングの実践の観点からすると、これは良いことではありません。セマンティクスを解釈できる状態にしておくためです。より良いアイデアは、コンテナへの参照を渡し、関数がコンテナを目的の要素で満たすようにすることです。

于 2011-02-17T21:15:43.533 に答える