【问题标题】:Does standard C++11 guarantee that temporary object passed to a function will have been created before function call?标准 C++11 是否保证传递给函数的临时对象将在函数调用之前创建?
【发布时间】:2016-08-08 20:02:37
【问题描述】:

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

即使临时对象传递为:

  1. 对象
  2. 右值引用
  3. 仅传递临时对象的成员

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 created吗?

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

【问题讨论】:

  • 我不明白这个问题。如果在它的主体开始执行时,它的参数还不存在,那么一个函数怎么会有用呢?
  • @underscore_d 在 C++ 中,它不可能是标准中明确描述的内容。但如果标准中没有描述,那么:1. function() 可以内联。 2. 可以在第一次使用该对象时构造对象,即使在函数的一些代码之后 - 因为编译器可以重新排序任何操作,如果它不改变 Observable 行为(没有输入/输出,内存-fences, ...) - § 1.9 程序执行 1、5、8。引用:“编译器可以随意重新排序指令和操作。” stackoverflow.com/questions/30606924/…
  • 对,#2 帮助我理解并提出了一个很好的观点,这似乎被排序要求所排除。我仍在等待 C++ 获得用于延迟初始化对象的本机语法...关于#1,我确信它仍然可以内联,对吗?只是编译器必须首先创建 3 个参数(它们之间的顺序不确定)并将它们保存在内联体中使用。

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


【解决方案1】:

[intro.execution]/16:

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

【讨论】:

    【解决方案2】:

    从 [expr.call]/8 我们有

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

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

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

    【讨论】:

      猜你喜欢
      • 2016-12-21
      • 2013-07-10
      • 1970-01-01
      • 2020-05-05
      • 1970-01-01
      • 2015-08-30
      • 1970-01-01
      • 2013-08-23
      • 1970-01-01
      相关资源
      最近更新 更多