13

次の関数があるとします。

void foo(std::vector<int> vec, int n);

次のように関数を呼び出すと:

std::vector<int> numbers { 2, 3, 5, 7, 11, 13, 17, 19 };
foo(std::move(numbers), numbers[0]);

すべての引数は、パラメータにバインドされる前に完全に評価されていますか? その場合、std::moveは単に を参照する xvalue を生成するため、無害numbersです。それとも、評価されるとすぐに、個々の引数をそのパラメーターにすぐにバインドできますか? その場合、はすでに に移動されている可能性がnumbers[0]あるため、未定義の動作を引き起こす可能性があります。numbersvec

4

1 に答える 1

10

§1.9/15 では、次のように伝えられています。

関数を呼び出すとき (関数がインラインかどうかに関係なく)、すべての値の計算と、任意の引数式、または呼び出された関数を指定する後置式に関連付けられた副作用は、関数の本体のすべての式またはステートメントの実行前に順序付けられます。と呼ばれる機能。(...)

そして§5.2.2/4:

(...) 各パラメーターの初期化と破棄は、呼び出し元の関数のコンテキスト内で発生します。(...)

最終草案には、他に関連するテキストは見つかりませんでした。これは、引数の評価とパラメーターの初期化の間の順序付きの前の関係を明示的に定義していないため、それらは順序付けstd::moveされておらず、無害ではありません。

この問題の解決策は、一時変数を使用してシーケンスを強制することです。

std::vector<int> numbers { 2, 3, 5, 7, 11, 13, 17, 19 };
int num = numbers[0];
foo(std::move(numbers), num);
于 2011-08-29T11:19:38.650 に答える