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

时间:2016-08-15 11:34:16

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

众所周知,标准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

     

完整表达式是一个不是子表达式的表达式   另一个表达。 [注意:在某些情况下,例如未评估   操作数,句法子表达式被认为是完整表达式   (第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);
}

0 个答案:

没有答案