2016-08-15 112 views
6

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

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

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

§12.2的临时对象

§12.2/5

有三个背景中的临时的在完整表达式的结尾的 不同点处销毁。第一个上下文 是调用缺省构造函数以初始化没有相应初始化程序(8.6)的 数组的元素。第二个上下文是 ,当复制构造函数被调用来复制数组的一个元素时, 整个数组被复制(5.1.5,12.8)。在任何一种情况下,如果 构造函数具有一个或多个默认参数,则在构造下一个数组元素(如果有)之前,对在默认参数中创建的每个临时文件的销毁进行排序。当引用被绑定到临时时,第三上下文是 。

另外:

§1.9/10

全表达是不是 另一表达子表达式的表达式。 [注意:在某些情况下,如未评估的 操作数,语法子表达式被认为是全表达式 (第5章)。 - 结束注释]如果语言结构被定义为产生一个函数的隐式调用,则为了该定义的目的,语言结构的使用被认为是一个表达式。 A 调用除了临时对象以外的对象 的生命周期结束时生成的析构函数是隐式的完整表达式。 为了满足 表达式 显示的语言结构的要求,应用于表达式结果的转换也被认为是完整表达式的一部分。

这是否意味着标准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 destroyed永远是func-end后?

而且这样的:

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

总是等于这个:

{ 
    T tmp1; T tmp2; T tmp3; 
    function(tmp1, tmp2, tmp3.val); 
} 
+3

你的最后一部分以“这和:”开头是不正确的,没有。 (逗号运算符的左对齐不适用于函数参数。)期待这个好问题的正确答案。 – Bathsheba

+2

你不相信我的回答吗? – NathanOliver

+0

@Bathsheba谢谢!错字固定。 – Alex

回答

7

好,我们已经报所有,它告诉我们临时的一生文本在年底结束全表达式。所以,是的,“T destroyed”将永远持续。

如果破坏没有观察到的副作用的话,每AS-if规则,它可以实际上发生在之后的任何时间和hellip;但这是没有意义的,因为它不会被观察到。

但是,您提交的最后两个片段不是,通常是等价物,因为您以某种不以前的方式修复了构建/初始化的顺序。函数参数具有未指定的评估顺序。不过,对于这个特殊的T,差别是不可观察的。

+2

只是一个小小的修复:你可能会说“永远会**最后**”。 –

+1

谢谢! “被摧毁”总是会首先或最后(最后)?关于“临时人的一生在完整表达式的结尾处结束” - 但是在这种情况下,这是不是可观察到的? http://ideone.com/DuY0GQ来自:https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Execute-Around_Pointer#Solution_and_Sample_Code – Alex

+0

@Yehezkel:哈哈是啊oops obvs –

相关问题