【问题标题】:Does standard C++11 guarantee that temporary object passed to a function will have been destroyed after the end of the function?标准 C++11 是否保证传递给函数的临时对象将在函数结束后被销毁?
【发布时间】:2016-12-21 14:42:18
【问题描述】:

众所周知,标准 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 临时对象

§ 12.2 / 5

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

还有:

§ 1.9 / 10

full-expression 是不是 另一种表达方式。 [注:在某些情况下,例如未评估 操作数,句法子表达式被认为是完整表达式 (第 5 条)。 — 尾注] 如果一个语言结构被定义为产生 函数的隐式调用,语言结构的使用是 就本定义而言,被视为一种表达方式。一种 调用在对象生命周期结束时生成的析构函数 除了临时对象之外,还有一个隐式的完整表达式。 应用于表达式结果的转换以满足 表达的语言结构的要求 出现也被认为是完整表达式的一部分。

这是否意味着标准 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);
}

【问题讨论】:

  • 您以“And this:”开头的最后一部分是不正确的,不。 (逗号运算符的从左到右不适用于函数参数。)期待这个好问题的正确答案。
  • 你不相信我的回答吗?
  • @Bathsheba 谢谢!错字已修复。
  • @Bathsheba 否,the one 上一个问题。
  • @Alex - tmp1tmp2tmp3 始终按此顺序创建,这一点存在显着差异。函数调用中的T() 值可以按任何顺序创建(编译器认为“最佳”的顺序)。

标签: c++ c++11 standards lazy-sequences sequence-points


【解决方案1】:

好吧,你已经引用了所有告诉我们临时生命周期在 full-expression 结尾处结束的文本。所以,是的,“T destroyed”永远排在最后。

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

但是,您提供的最后两个 sn-ps通常不等效,因为您以前所未有的方式固定了构造/初始化的顺序。函数参数具有未指定的评估顺序。不过,对于这个特定的T,同样无法观察到差异。

【讨论】:

  • 只是一个小问题:您可能是想说“总会来last”。
  • 谢谢! “T被摧毁​​”总是先出现 - 还是最后(最后)?关于“临时的生命周期在完整表达结束时结束”-但这在这种情况下也不能观察到吗? ideone.com/DuY0GQ 取自:en.wikibooks.org/wiki/More_C%2B%2B_Idioms/…
  • @Yehezkel: 哈哈是的,哎呀 obvs
  • @Alex:不确定您对新代码的要求是什么。它表现出与上述相同的行为。
猜你喜欢
  • 1970-01-01
  • 2019-08-19
  • 2013-07-10
  • 2020-05-05
  • 1970-01-01
  • 1970-01-01
  • 2015-08-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多