Подтвердить что ты не робот

Является ли привязка параметров секвенированной после оценки аргумента?

Предположим, что у меня есть следующая функция:

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 безвреден, потому что он просто дает значение x, относящееся к numbers. Или каждый отдельный аргумент может быть сразу привязан к его параметру сразу после его оценки? В этом случае numbers[0] может вызвать поведение undefined, поскольку numbers уже может быть перенесен в vec.

4b9b3361

Ответ 1

On & sect; 1.9/15 нам говорят, что:

При вызове функции (независимо от того, является ли функция встроенной), каждое вычисление значения и побочный эффект, связанное с любым выражением аргумента, или с выражением postfix, обозначающим вызываемую функцию, является секвенированы перед выполнением каждого выражения или выражения в теле вызываемой функции. (...)

И по & sect; 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);