标准C ++ 11是否保证在函数调用之前创建传递给函数的临时对象?

时间:2016-08-08 20:02:38

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

标准C ++ 11是否保证在开始执行函数之前创建了所有3个临时对象?

即使临时对象传递为:

  1. 物体
  2. 右值参考
  3. 仅传递临时对象的成员
  4. http://ideone.com/EV0hSP

    #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 
    

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

      

    §5.2.2函数调用

         

    §5.2.2

         

    1函数调用是一个后缀   表达式后面跟一个可能为空的括号,   以逗号分隔的初始化子句列表,构成了   函数的参数。

    func-start 之后可以是 T创建中的任何一个吗?

    或者有没有办法将参数作为g / r / l / x / pr-value传递,以便在创建临时对象之前启动函数?

    enter image description here

2 个答案:

答案 0 :(得分:11)

[intro.execution]/16

  

调用函数时(无论函数是否为内联函数),每次都是   值计算和与任何参数相关的副作用   表达式,或使用指定被调用的后缀表达式   函数,在执行每个表达式之前排序或   被调用函数体中的语句。

答案 1 :(得分:7)

从[expr.call] / 8我们有

  

[注意:后缀表达式和参数的评估都是相对于彼此的无法排序的。在输入函数之前,对参数评估的所有副作用进行排序(参见1.9)。 - 后注]

这意味着在输入函数之前构造所有参数。

因此,这也保证了在函数退出后所有参数都被销毁。