Гарантирует ли стандарт C++11, что временный объект, переданный функции, будет создан до вызова функции?
Гарантирует ли стандарт C++11, что все 3 временных объекта были созданы до начала выполнения функции?
Даже если временный объект передан как:
- объект
- Rvalue ссылка
- передан только член временного объекта
#include <iostream>
using namespace std;
struct T {
T() { std::cout << "T created \n"; }
int val = 0;
~T() { std::cout << "T destroyed \n"; }
};
void function(T t_obj, T &&t, int &&val) {
std::cout << "func-start \n";
std::cout << t_obj.val << ", " << t.val << ", " << val << std::endl;
std::cout << "func-end \n";
}
int main() {
function(T(), T(), T().val);
return 0;
}
Выход:
T created
T created
T created
func-start
0, 0, 0
func-end
T destroyed
T destroyed
T destroyed
Рабочий проект, Стандарт для языка программирования C++ 2016-07-12: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4606.pdf
§ 5.2.2 Вызов функции
§ 5.2.2
1 Вызов функции - это постфиксное выражение, за которым следуют круглые скобки, содержащие возможно пустой, разделенный запятыми список предложений инициализатора, которые составляют аргументы функции.
Но может ли любой из T быть создан после func-start?
Или есть ли способ передать аргументы как g/r/l/x/pr-значение, чтобы функция запускалась до создания временного объекта?
2 ответа
При вызове функции (независимо от того, является ли функция встроенной), каждое вычисление значения и побочный эффект, связанный с любым выражением аргумента или с выражением постфикса, обозначающим вызываемую функцию, упорядочивается перед выполнением каждого выражения или оператора в теле вызываемая функция.
Из [expr.call]/8 мы имеем
[Примечание: оценки выражения postfix и аргументов не являются последовательными по отношению друг к другу. Все побочные эффекты при оценке аргументов секвенируются до входа в функцию (см. 1.9). —Конечная записка]
Это означает, что все параметры строятся до ввода функции.
Следовательно, это также гарантирует, что все параметры будут уничтожены после выхода из функции.