const, связанный с временной инициализацией этой ссылки в конструкторе

Рассмотрим следующий код:

#include  struct A { const char *name; A() : name("A") { std::cout << "A()\n"; } virtual ~A() { std::cout << "~A()\n"; } }; class B { const A& a; public: B() : a(A()) { }; void print_data() const { std::cout << a.name << '\n'; } ~B() { std::cout << "~B()\n"; } }; int main() { B b; b.print_data(); return 0; } 

Выход из GCC 4.4:

A () ~ A () A ~ B ()

Мне это кажется странным. Я ожидал, что либо экземпляр временного экземпляра A будет привязан к B :: a, либо это временное само разрушается во время ~ B ().

В принципе, я думал, что B :: a всегда является действительной ссылкой в ​​течение жизни b. Фактически b.print_data () работает, очевидно, и компилятор не дает никаких предупреждений.

Что говорит об этом стандартное c ++ 98/03?

Постоянные ссылки не продлевают срок жизни в classах, период. Это просто так. Они делают это только в Foo const& f = Foo(); где foo возвращает значение, но это все.

§12.2 [class.temporary]

p4 Существует два контекста, в которых временные объекты уничтожаются в другой точке, чем конец полного выражения. […]

p5 Второй контекст – это когда ссылка привязана к временному. Временное, к которому привязана ссылка, или временный объект, являющийся полным объектом для подобъекта, связанного с временной привязкой, сохраняется для срока службы ссылки, за исключением случаев, указанных ниже. Временная привязка к ссылочному элементу в ctor-инициализаторе конструктора (12.6.2) сохраняется до тех пор, пока конструктор не выйдет .

Ваш код включает неопределенное поведение. Временное разрушается, когда конструктор B выходит (C ++ 03, [class.temporary]):

Временная привязка к ссылочному элементу в ctor-инициализаторе конструктора (12.6.2) сохраняется до тех пор, пока конструктор не выйдет.

Попробуйте изменить:

 B() : a(A()) { cout << "B()\n"; }; 

Ты получишь:

 A() B() ~A() A ~B()