2016-07-17 28 views
0

は、私はこのベクターは、(サイズはメガバイト)は非常に大きくなりますオブジェクト大きなデータ構造を効率的に返す方法。

std::vector<int> data; 

のベクトルを持っていると言います。私はこのデータ構造を返す必要がある関数を持っています。私がこのデータ構造を「価値によって」返すと、ベクターのコピーが作られますか?

std::vector<int> generate() 
{ 
    std::vector<int> data; 
    //Populate data 
    return data; 
} 

この操作は、ベクターをヒープに割り当ててポインタをベクターに渡すことと比べて効率的ですか?

std::vector<int>* generate() 
{ 
    std::vector<int>* data = new std::vector<int>(); 
    //Populate data 
    return data; 
} 
+0

ポインタを戻すと、手動でメモリ管理する必要があります。したがって、それを追跡するために追加するすべてのコードを考慮する必要があります。 –

答えて

4

現代のコンパイラは、単純な移動にこれを最適化する方法を知って交換しました。あなたの最初の例は十分に効率的です。他に何もする必要はありません。

+1

古いコンパイラでも、これを最適化する方法(RVOとNRVO)によってコピーのエリートが可能です。 –

0

あなたは最初は空std::vectorを通過した後、次のようにあなたのコードの構造が許す場合には、参照によって返すことができます:

std::vector<int>& generate(std::vector<int>& _vec) { 
    // populate _vec 
    return _vec; 
} 

これは、ポインタを使用するか、コピーを作成することから保存されます。あなたは、C++ 11のベクトルを移動することができ、それが非常に安くなって使用する場合

+4

これは10年前に「大丈夫」だった。それは時代遅れであり、現代のコードでは存在しません。 – ildjarn

+0

@ildjarn確かに、最良の解決策ではないかもしれませんが、解決策です。それを取るか、それを残す。 – ArchbishopOfBanterbury

+2

_improvement_でなければ解決策ではありません。 – ildjarn

0

は、単にいくつかの単語は

5

ほとんどのコンパイラは、NRVOの名前付き戻り値の最適化を実行します。つまり、データはコピーされませんが、保証されません。 NRVOが使用されない場合があります。 C++ 11以降では、ベクトルは依然として非常に効率的な移動セマンティクスを使用することがあります。

明確にするために、[編集]

、あなたがC++ 11互換性のあるコンパイラを使用する場合は、参照することにより、C++ 03、関数のパラメータ(より良いリターン安全であるとして立ち往生しているならば、あなたのコードは、効率的です)、いくつかのコンテキストでは、コピーを終了する可能性があります。

+0

そしてC++ 17 _guarantees_ copy-elisionです。 – ildjarn

関連する問題