标准C 11是否保证传递给函数的临时对象在函数结束后会被销毁?

众所周知,标准C 11保证传递给函数的临时对象将在函数调用之前创建:Does standard C++11 guarantee that temporary object passed to a function will have been created before function call?

但是,标准C 11是否保证传递给函数的临时对象在函数结束后(之前没有)被销毁?

工作草案,编程语言标准C 2016-07-12:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4606.pdf

§ 12.2 Temporary objects

§ 12.2 / 5

There are three contexts in which temporaries are destroyed at a
different point than the end of the full expression.
The first context
is when a default constructor is called to initialize an element of an
array with no corresponding initializer (8.6). The second context is
when a copy constructor is called to copy an element of an array while
the entire array is copied (5.1.5, 12.8). In either case, if the
constructor has one or more default arguments, the destruction of
every temporary created in a default argument is sequenced before the
construction of the next array element, if any. The third context is
when a reference is bound to a temporary.

也:

§ 1.9 / 10

A full-expression is an expression that is not a subexpression of
another expression. [ Note: in some contexts, such as unevaluated
operands, a syntactic subexpression is considered a full-expression
(Clause 5). — end note ] If a language construct is defined to produce
an implicit call of a function, a use of the language construct is
considered to be an expression for the purposes of this definition. A
call to a destructor generated at the end of the lifetime of an object
other than a temporary object is an implicit full-expression.
Conversions applied to the result of an expression in order to satisfy
the requirements of the language construct in which the expression
appears are also considered to be part of the full-expression.

这是否意味着标准C 11保证传递给函数的临时对象不会在函数结束之前被破坏 – 并且恰好在完整表达式的末尾?

http://ideone.com/GbEPaK

#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 

我们可以说被摧毁的T总会在func-end之后吗?

还有这个:

function(T(), T(), T().val);

总是等于这个:

{
    T tmp1; T tmp2; T tmp3;
    function(tmp1, tmp2, tmp3.val);
}
最佳答案
好吧,你已经引用了所有文字告诉我们临时的生命周期在完整表达结束时结束.所以,是的,“T毁灭”将永远是最后的.

如果破坏没有可观察到的副作用那么,按照as-if规则,它实际上可能在之后的任何时间发生……但这没有实际意义,因为它是不可观察的.

但是,您提供的最后两个片段通常不等同,因为您以前所未有的方式修复了构造/初始化的顺序.函数参数具有未指定的评估顺序.但是,对于这个特定的T,差异是不可观察的.

转载注明原文:标准C 11是否保证传递给函数的临时对象在函数结束后会被销毁? - 代码日志