このコード:C++の戻り値の最適化
#include <vector>
std::vector<float> getstdvec() {
std::vector<float> v(4);
v[0] = 1;
v[1] = 2;
v[2] = 3;
v[3] = 4;
return v;
}
int main() {
std::vector<float> v(4);
for (int i = 0; i != 1000; ++i)
{
v = getstdvec();
}
}
ここに私の間違った理解は、機能getstdvecが実際にそれを返すだベクトルを割り当てる必要がないということです。私がvalgrind/callgrindでこれを実行すると、mallocに1001の呼び出しがあることがわかります。 mainの初期ベクトル宣言では1、すべてのループ反復では1000です。
何がありますか?どのように私は毎回それを割り当てることなく、このような関数からベクトル(または他のオブジェクト)を返すことができますか?
編集:私は参考にベクトルを渡すことができます。私は、不要な割り当てを発生させることなくオブジェクトを返すような、このような関数を書くことが可能であった(そしてさらに好ましい)という印象を受けていました。
あなたの編集のために、参考にならない解決策を提供するために、この極小のサンプルコードではなく、解決しようとしている問題の実際の例が必要です。 –
@マークB、それは本当に単純です:私は不要なコピー/割り当てを行うことなくベクトルを返す関数が必要です。私は、RVOまたは右辺値に関連する何かがこの非常に簡単なことを可能にする印象を受けました。現実世界の単純な例は、ベクトルyとx、スカラーkに対してy = k * xを実行しようとしています。従来のpass-by-reference関数は 'void mult(const float&k、const vec&x、vec&y)'のようになります。しかし明らかに関数呼び出し 'y = mult(k、x)'は 'mult(k、x、y)'よりも好ましい。 – Aurelius
RVO(戻り値の最適化)は、コンパイラがコードに対して行う処理です。コードでは、まず最適化できるものを実行する必要があります(一時的なものを渡して、同じオブジェクトに戻すなど)。あなたはそのコードを見て、おそらく、私はgetstdvecへの参照を渡すことで最適化できると考えました。なぜコンパイラーはそれをしないのですか?さて、参照を渡すことはあなたのコードに暗示されていません。コンパイラは、コードが行うことを最適化することしか期待できません。 – iheanyi