void foo(const Object & o = Object()) {
return;
}
在上面的函数中,什么时候〜应该调用对象?当函数退出时或者在调用站点周围的块的末尾?
答案 0 :(得分:9)
默认参数将在包含函数调用的完整表达式的末尾被销毁。
答案 1 :(得分:6)
详细说明 David 所说的内容,该标准在 12.2 [class.temporary] 部分中说明:
有两种情况下,临时状态被摧毁 不同于完整表达的结束点。 [...] 第二 context是指引用绑定到临时的。临时到 哪个引用绑定或临时是完整的 绑定引用的子对象的对象仍然存在 参考的有效期除外:
- ...
- 函数调用(5.2.2)中的引用参数的临时绑定将持续到完整表达式完成 包含电话。
- ...
因此,当函数退出时,或者当包含调用的块结束时,它们既不会被破坏,而是在包含函数调用的完整语句的末尾(简单地说,在函数调用后的第一个分号处,在调用中)上下文)。
编辑:所以说我们得到了:
int foo(const Object & o = Object());
some_stuff();
std::cout << (foo() + 7);
other_stuff();
这大致相当于以下(注意概念范围块):
some_stuff();
{
Object o; // create temprorary
int i = foo(o); // and use it
int j = i + 7; // do other things
std::cout << j; // while o still alive
} // finally destroy o
other_stuff();
编辑:正如 Michael 在评论中指出的那样,我给出的“声明/分号” -analogy是一个简化的术语“完整表达”并且有些情况会有点不同,例如他的例子:
if(foo()) bar();
在调用bar
之前会破坏临时值,因此与表达式语句不同:
foo() ? bar() : 0;
但是,“分号” -analogy通常是一个很好的选择,即使完整表达式不一定与语句(可以包含多个完整表达式)相同。
答案 2 :(得分:0)
我认为这段代码不应该编译。除非是const
,否则不能将引用绑定到临时引用。如果它是const
,则临时应保持活动直到函数表达式结束。与其中定义的局部变量相同。