7

这个输出F~,但我期待~F

#include <iostream>

struct Foo {
    int _x;
    operator const int & () const {return _x;}
    ~ Foo () {std :: cout << "~";}
};

void foo (const int &)
{
    std :: cout << "F";
}

int main ()
{
    foo (Foo ());
}

我将其构建为一个反例,以表明最重要的常量是一个例外而不是规则。它通常写成

当 const 引用绑定到临时对象时,该临时对象的生命周期会延长到引用的生命周期

我试图说明,虽然Foo()是临时的,_x但转换运算符返回的引用不是,并且上面的代码是不安全的。

但是输出似乎证明了该示例安全的,临时对象的生命周期Foo()因存在对其成员之一的 const 引用而延长。

这是正确的吗?这在标准中的什么地方有规定?

4

4 回答 4

6

关于临时工的一般规则是,当他们作为一部分的完整表达结束时(非正式地,当到达 时;),他们的生命就结束了。

12.2 临时对象

3/ [...] 临时对象作为评估完整表达式 (1.9) 的最后一步被销毁,该完整表达式 (从词法上) 包含创建它们的点。即使评估以抛出异常结束也是如此。销毁临时对象的值计算和副作用仅与完整表达式相关联,与任何特定子表达式无关。

于 2011-11-15T09:58:01.277 回答
1

那是因为临时在函数调用的整个过程中都存在。当你这样做foo (Foo ());时,会发生什么:

  1. 临时Foo构造,然后
  2. operator const int&临时调用
  3. foo()被调用并且这个输出F
  4. 一旦foo()返回临时Foo被破坏并且这个输出~
于 2011-11-15T09:54:49.577 回答
1

这里没有魔法。所有函数参数都存在于调用者的范围内,包括临时参数。临时Foo()在调用者的范围内构造,并在行尾销毁。

因此,无论函数foo()做什么,都会其参数main()被销毁之前发生。

于 2011-11-15T09:56:22.037 回答
0

但是Foo这里的实例总是会一直存在,直到分号结束创建它的语句。将对成员的引用传递给函数调用并没有改变这一点。

尝试:

int const &ref = Foo();
foo(ref);

相对

Foo const &ref = Foo(); // or function returning temp
foo(ref);
于 2011-11-15T09:58:23.770 回答