5

ISO/IEC 14882:2011(E) (C++11) の § 17.6.4.9 から:

次のそれぞれは、特に明記されていない限り、C++ 標準ライブラリで定義されている関数のすべての引数に適用されます。
[中略]
— 関数の引数が右辺値参照パラメーターにバインドされている場合、実装は、このパラメーターがこの引数への一意の参照であると想定する場合があります。

この仕様は標準ライブラリ関数にのみ適用されますが、右辺値参照の全体的なポイントは、この種の仮定が可能であるように思われます。右辺値参照を受け取り、それを渡す関数がある場合 (一時的または を介し​​てstd::move)、実装はそれが一意であると想定する最適化を合法的に実行できますか? そうでない場合、とにかくそうする実装はありますか?

4

1 に答える 1

5

言語自体は、右辺値参照が他のオブジェクトをエイリアスできないことを義務付けているわけではありません。これは、標準ライブラリ関数の前提条件として述べられているだけです。したがって、「実装」がコンパイラを意味する場合、いいえ - コンパイラは、この要件に基づいて最適化を実行しません。確かに、あなたが書いたコードではそうではありません。

特定のコンパイラに、コードがエイリアシング情報を伝えることを可能にするある種の拡張機能がある場合、その前提条件により、標準ライブラリ関数がそのような拡張機能を利用できるようになります。この種のエイリアシング情報により、コンパイラはいくつかの最適化を実行できる場合があります。

いずれにせよ、ステートメントの主な結果は、標準ライブラリの実装が、関数パラメーターの不当なエイリアシングに直面しても合理的に動作する必要がないということです。たとえば、ペアを構築する場合

std::vector<int> some_vector(100, 42);
auto p = std::make_pair(std::move(some_vector), some_vector);

という保証はありませんp.first == p.second

左辺値参照パラメーターにこのような要件がないということはvector.insert(vector.end(), vector[3])、ベクトルを再割り当てする必要がある場合でも、標準ライブラリーがコードのようなコードが機能することを確認するために、いくつかのクレイジーなことをしなければならないことを意味します。委員会は、実装が右辺値のエイリアシングを検出し、場合によっては移動のみを行う必要があることは非現実的だと考えていたと思います。

于 2013-08-02T23:06:32.800 に答える