2013-02-06 39 views
18

我被以下示例在聊天:哪种标准措辞告诉我们,只有“ref-to-const”临时生命周期延长“有效”?

#include <iostream> 
struct foo { ~foo() { std::cout << "destroying!\n"; } }; 
const foo& func(const foo& a, const foo&) { return a; } 

int main() 
{ 
    foo x; 
    const foo& y = func(foo(), x); 
    std::cout << "main\n"; 
} 

Output

destroying! 
main 
destroying! 

这似乎表明,foo临时的寿命没有延伸到的main整体,即使它得到绑定到该范围内的ref-const

那么可以推测,延长寿命只是“一次工作”;即在func的参数初始化时应用,但不通过连续绑定传递。

我的解释是否正确?如果是这样(以及是否有任何单独的段落可直接适用),定义此行为的标准措辞是什么?

+0

“func”的第二个参数是什么?如果将它(和'x')关闭,会发生什么? –

+0

@KonradRudolph:我猜,它是为了演示相对于文本'“main”输出的破坏顺序。 –

回答

7

这是两个问题报告的主题,http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1299http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1568

前者问题的报告,其中我是记者,是为了覆盖所有这些情况下,一个引用绑定到一个临时对象,但并非是延长寿命,。该问题正文中的描述仅提到了与临时表达式混淆的价值(实际上决定了他们评估的生命周期是否延长或不延长)。但是左值和x值同样在标准中与这些混淆。在static_cast的情况下发生的一个例子是问题编号#1568(其中使用“临时变量”进一步混淆了此事)。

实际上,这样的:

临时结合到在一个函数调用(5.2参考参数。2)一直持续到包含该调用的完整表达式的完成。

与本段落中的其他规则相矛盾。因为临时数据绑定到都是函数调用中的引用参数和本地自动引用变量。

+0

是的,你和詹姆斯已经说服了我,“除了”这个词不会消除这个段落的规则,因为“except”一次只能应用于一个场景,因此不能消除两个或两个更矛盾的情况。 –

8

你几乎是正确的。这种行为实际上来自于函数调用,并不是因为任何一种“只能工作一次”的规则。

这里的整个寿命延长“功能”的措辞,与相关的规则以粗体强调:

[C++11: 12.2/5]:[..]到的引用绑定暂时或临时性的即是到该参考被结合的子对象的完整的对象持续基准的寿命除了

  • [..]
  • 临时绑定到函数调用(5.2.2)中的引用参数,直到完成包含调用的完整表达式。
  • [..]
+0

但在这种情况下,临时也被绑定到const引用'y'。那么哪个参考控制其使用期限? –

+1

@JamesKanze:我看到“除了”列表优先。 –

+0

我有点不明白你的意思,但我仍然认为它是模棱两可的,如果这是意图,有点指定它的折磨方式。首先,你保证延长生命周期的唯一基础是否引用是否被绑定到一个临时的,然后你消除所有可能导致间接性的情况,希望你已经得到了他们所有的(他们可能没有的) 。 –

3

这适用于这里是常识的规则。标准是 措辞不佳,事实上确保这一点。但是没有实用的实用方法。

+0

你是什么意思?没有切实可行的方法来实施限制,或实施目前尚未发生的寿命延长? –

+0

@LightnessRacesinOrbit没有实际的方法强迫临时的生命周期扩展到它所绑定的最后一个引用。 –

+0

我认为@詹姆斯正在谈论我在我的回答中总结的内容。 –

1

也许我有点慢,但对我来说,它不清楚这个问题的解决方案是从阅读其他答案。因此,我修改了显示的代码并希望为其他人进行总结:答案是,您获得未定义的行为如果您访问y

运行这段代码:

struct foo { 
    int id; 
    foo(int id) : id(id) { std::cout << "ctor " << id << std::endl; }; 
    ~foo() { std::cout << "dtor " << id << std::endl; } 
}; 
const foo& func(const foo& a, const foo&) { return a; } 

int main(int argc, char** argv) { 
    foo x(1); 
    const foo& y = func(foo(2), x); 
    std::cout << "main " << y.id << std::endl; 
    return 0; 
} 

输出对我来说是:

ctor 1 
ctor 2 
dtor 2 
main 2 
dtor 1 

但线路main 2不确定的行为

相关问题