Ссылка на неназванный временный объект (время жизни)
Прочитав этот ответ от 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
3 ответа
Почему это возможно?
Потому что стандарт так говорит, потому что он считается полезным. Rvalue ссылки и const
Ссылки на lvalue продлевают время жизни временных:
[C++11: 12.2/5]:
[..] Временный объект, к которому привязана ссылка, или временный объект, являющийся полным объектом подобъекта, к которому привязана ссылка, сохраняется в течение всего времени существования ссылки, кроме [..]
и исчерпывающая формулировка в [C++11: 8.5.3/5]
требует, чтобы мы не связывали временныеconst
lvalue ссылки.
Это указано в стандарте C++? Какая версия?
Да. Все они.
Временная привязка к константной ссылке увеличивает время жизни временной привязки до времени жизни постоянной ссылки.
Хорошо для чтения:
ПОЛУЧИЛСЯ № 88: Кандидат на "Самый важный const"
Да, это указано в стандарте C++ со времени введения ссылок.
Так что, если вам интересно, если это функция C++11, нет, это не так. Это уже существовало в C++03.
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;
}