2

名前付きパラメーターコードを開発することを考えていましたが、次のようなコードを考えるようになりました。

#include <utility>

int main() 
{
  using std::make_pair;
  auto x = make_pair(1, make_pair(2, make_pair(3, make_pair(4,5))));
}

これを単純に実装すると、最初に「make_pair(4,5)」を実行し、次に結果を「make_pair(3、...)」の2番目の要素にコピーしてから、「make_pair」の2番目の要素にコピーします。 (2、...)」など。

これにより、残念ながらO(n ^ 2)のパフォーマンスが発生し、不要なコピーが多数発生します。ここでも、(名前付きの)戻り値の最適化がどのように役立つかわかりません。

理想的には、それがの最後の場所にあることをmake_pair(4,5) 認識xし、その場所に自分自身を構築します。

これをさらに進める:

#include <utility>

int main() 
{
  using std::make_pair;
  auto&& x1 = make_pair(3, make_pair(4,5));
  auto x2 = make_pair(1, make_pair(2, std::move(x1)));
}

このようなコードのコピーも避けたいです。

この最適化は非常に明白なので、コンパイラーがそれを実行すると想定する必要がありますか、それともコピーを回避するためにこれをコーディングする別の方法がありますか?

4

2 に答える 2

5

[N]RVO は、このような場合に役立ちます。基本的に何が起こるかというと、1 つの複合オブジェクトが割り当てられ、各関数からの「戻り値」が、結果を保持するオブジェクトに直接渡されることになります。

これの多くを (特に C++11 で) 行う場合は、代わりにタプルを使用する方がほぼ確実にクリーンでシンプルで直接的なので、次のようにします。

auto x = make_pair(1, make_pair(2, make_pair(3, make_pair(4,5))));

次のようになります。

auto x = make_tuple(1, 2, 3, 4, 5);

これはおそらく生成されたコードにはあまり影響しませんが、(少なくとも IMO) 読みやすくなっています。

于 2011-05-02T06:06:15.040 に答える
1
make_pair(1, make_pair(2, make_pair(3, make_pair(4,5))));

別の make_pair への引数であるすべての make_pair は、右辺値参照として扱われる一時を作成するため、コピーされません。

本当に欲しいのはmake_tupleだと思います。

于 2011-05-02T06:08:05.000 に答える