对未命名临时对象(生命周期)的引用

5

阅读完来自ildjarn这个答案后,我编写了以下示例,看起来一个未命名的临时对象与其引用具有相同的生命周期!

  • 为什么会这样?
  • 是否在C++标准中指定?
  • 哪个版本?

源代码:

#include <iostream>  //cout
#include <sstream>   //ostringstream 

int main ()
{
        std::ostringstream oss;
        oss << 1234;

        std::string const& str = oss.str();
        char        const* ptr = str.c_str();

        // Change the stream content
        oss << "_more_stuff_";
        oss.str(""); //reset
        oss << "Beginning";
        std::cout << oss.str() <<'\n';

        // Fill the call stack
        // ... create many local variables, call functions...

        // Change again the stream content
        oss << "Again";
        oss.str(""); //reset
        oss << "Next should be '1234': ";
        std::cout << oss.str() <<'\n';

        // Check if the ptr is still unchanged
        std::cout << ptr << std::endl;
}

执行:

> g++ --version
g++ (GCC) 4.1.2 20080704 (Red Hat 4.1.2-54)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
> g++ main.cpp -O3
> ./a.out
Beginning
Next should be '1234':
1234

4
在你的C++书中,应该早期就涵盖了const引用延长临时对象生命周期的事实。 - Lightness Races in Orbit
1
如果你尝试在网上搜索你使用的短语:“临时对象与其引用具有相同的生命周期”,你应该能找到答案。 - Jonathan Wakely
1
可能是临时变量的生命周期的重复问题 / 看看我发现了什么 - Lightness Races in Orbit
2
@olibre:是的,你说得对。我一定是喝醉了。 - Lightness Races in Orbit
1
@olibre: 你不能这样做. - Lightness Races in Orbit
显示剩余6条评论
3个回答

10
这怎么可能呢?因为标准是这样规定的,并且被认为是有用的。rvalue引用和const左值引用可以延长临时对象的生命周期,如下所述:
[C++11: 12.2/5]: [...] 引用绑定的临时对象或引用绑定的子对象作为完整对象的临时对象在引用的生存期内持久存在,但有例外情况。
此外,[C++11: 8.5.3/5] 的详尽措辞要求我们不得将临时对象绑定到非const左值引用上。
问:这在C++标准中有说明吗?是哪个版本?
答:是的,所有版本都有。

6

一个被const引用绑定的临时对象,会增加其生命周期,直到常量引用的生命周期结束。

好文推荐:

GotW #88: 一个候选“最重要的const”


是的,在引入引用的时候,这已经在C++标准中指定了。
所以,如果你想知道这是否是C++11的特性,不是的。它在C++03中已经存在了。


4

Lightness Races in Orbit是正确的。我认为这个例子会更加简洁。

#include <iostream>  //cout
#include <string>

int main ()
{
    using namespace std;
    int a = 123;
    int b = 123;
//  int       & a_b = a + b; // error!
    int const & a_b = a + b;
    cout<<"hello world!"<<endl;
    cout<<a_b<<endl;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接