众所周知,该标准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保证传递给函数的临时对象在函数结束之前不会被破坏 - 而且恰好在完整表达式的结尾?
#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);
}
你的最后一部分以“这和:”开头是不正确的,没有。 (逗号运算符的左对齐不适用于函数参数。)期待这个好问题的正确答案。 – Bathsheba
你不相信我的回答吗? – NathanOliver
@Bathsheba谢谢!错字固定。 – Alex