不是最重要的常数..但这是什么?

时间:2011-11-15 09:49:09

标签: c++ reference const object-lifetime

这会输出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是一个例外而不是规则。它通常写成

  

当const引用绑定到临时引用时,那个临时引用的生命周期延长到引用的生命周期

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

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

这是对的吗?标准中的哪个指定了?

4 个答案:

答案 0 :(得分:6)

关于临时性的一般规则是,当他们完全表达时,他们的生命就会结束(非正式地,到达;时)。

  

12.2临时对象

     

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

答案 1 :(得分:1)

这是因为临时在函数调用的整个持续时间内存活。当您执行foo (Foo ());时会发生什么:

  1. 临时Foo已构建,然后
  2. 在临时上调用
  3. operator const int&
  4. foo()被调用,并输出F
  5. 一旦foo()返回临时Foo被销毁,此输出~

答案 2 :(得分:1)

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

因此无论函数foo()在之前发生了什么main()中的参数都会被销毁。

答案 3 :(得分:0)

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

尝试:

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

Foo const &ref = Foo(); // or function returning temp
foo(ref);