当分配给const&时,C++的生命周期临时扩展到词法

pau*_*doo 2 c++ scope lifetime

最近我惊讶地发现C++中的临时变量被提升为具有完整的词法范围:

class Foo {
public:
    Foo() {
        std::cout << "A";
    }
    ~Foo() {
        std::cout << "B";
    }
};

int main(void)
{
    // Prints "ACB", showing the temporary being promoted to having lexical scope.
    const Foo& f = Foo();
    std::cout << "C";
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

除了将临时值分配给引用的可疑行为之外,这实际上工作正常(在VS2010和G ++ v4.1中测试).输出ACB显示临时对象已被提升为具有词法范围,并且仅在函数结束时被破坏(B在之后打印C).


其他临时变量的行为不是这样的:

int main(void)
{
    // Prints "ACBD", showing that the temporary is destroyed before the next sequence point.
    const int f = ((Foo(), std::cout << "C"), 5);
    std::cout << "D";
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

根据我的代码注释打印ACBD,显示临时变量保持到整个表达式完成评估(C之前打印的原因B),但仍然在下一个序列点之前销毁(为什么B之前打印D).(这种行为是我认为C++中的所有临时变量都有效的方式.我对之前的行为感到非常惊讶.)

有人可以解释什么时候合法的临时升级有这样的词汇范围?

And*_*owl 5

临时的生命周期绑定到常量左值引用或右值引用(自C++ 11以来)延长到该引用的生命周期.在第二种情况下,您在赋值的左侧没有引用,而是一个值,因此临时的生命周期不会延长.

参见C++ 11标准的12.2/4和12.2/5:

有两种情况,临时表演在不同于完整表达结束时被摧毁.第一个上下文是调用默认构造函数来初始化数组的元素[...]

第二个上下文是引用绑定到临时的.引用绑定的临时值或作为绑定引用的子对象的完整对象的临时值在引用的生命周期内持续存在,除了:[...]

接下来的"除"是指不适用于这种情况下的情况.