Что означает "Это не работает для ссылок, которые являются членами объектов" в GotW #88?

Херб Саттер:

Эффективный параллелизм: используйте иерархии блокировки, чтобы избежать тупиковых ситуаций. Эффективный параллелизм: нарушите закон Амдала! "ПОЛУЧИЛСЯ № 88: Кандидат на" Самое важное const "2008-01-01 от Херба Саттера Один мой друг недавно спросил меня, является ли приведенный ниже пример 1 законным, и если да, то что это значит. Это привело к приятной дискуссии, которую я решил опубликовать здесь. Поскольку он уже был близок к стилю GotW, я подумал, что после всех этих лет я сделаю еще один почетный... нет, я не принял новогоднюю резолюцию о возобновлении написания обычных GotW.:-)

JG Вопросы Q1: Является ли следующий код допустимым C++?

// Example 1

string f() { return "abc"; }

void g() {
const string& s = f();
  cout << s << endl;    // can we still use the "temporary" object?
}

A1: да. Это особенность C++... код действителен и делает именно то, что кажется.

Обычно временный объект длится только до конца полного выражения, в котором он появляется. Тем не менее, C++ намеренно указывает, что привязка временного объекта к ссылке на const в стеке удлиняет время жизни временного объекта до времени жизни самой ссылки и, таким образом, позволяет избежать того, что в противном случае было бы распространенной ошибкой висячих ссылок. В приведенном выше примере временное значение, возвращаемое функцией f(), сохраняется до закрывающей фигурной скобки. (Обратите внимание, что это применимо только к ссылкам на основе стека. Это не работает для ссылок, которые являются членами объектов.)

Первоначально я думаю, что последнее предложение означает:

class A 
{
public:
    int x;
    A(const int& x_)
    {
        x = x_;
    }
};

int main()
{
    A a(1); // assign lvalue to const int&
    std::cout << a.x;
}

Тем не менее, он работает нормально, по-видимому.

Итак, что означает "Это не работает для ссылок, которые являются членами объектов"?

1 ответ

Решение

Это означает, что если вы делаете что-то вроде этого:

string f() { return "abc"; }

struct foo {
  string const & _s;
  foo() : _s(f()) {}
};

Это не продлит жизнь временному возвращенному из f, И ссылка _s будет болтаться

Продление срока службы временных файлов является свойством ссылок с автоматическим сроком хранения. Т.е. локальные переменные в области действия функции.

Другие вопросы по тегам