Я отвечу на ваш вопрос ... наоборот.
Почему они позволили Foo const& foo = fooByValue();
начать с?
Это делает жизнь (несколько) легче, но повсюду вводит потенциально неопределенное поведение.
Foo const& fooByReference()
{
return fooByValue(); // error: returning a reference to a temporary
}
Это, очевидно, неправильно, и действительно, компилятор покорно сообщит об этом. Согласно комментарию Томалака: стандарт не обязателен, но хорошие компиляторы должны сообщать об этом. Clang, GCC и MSVC делают. Я думаю, что Comeau и ICC тоже.
Foo const& fooByIndirectReference()
{
Foo const& foo = fooByValue(); // OK, you're allowed to bind a temporary
return foo; // Generally accepted
}
Это неправильно, но более тонко. Проблема заключается в том, что время жизни временного объекта связано с временем жизни foo
, которое выходит из области видимости в конце функции. копия из foo
передается вызывающей стороне, и эта копия указывает в эфир.
Я поднял ошибку на Clang, и Argyris смог диагностировать этот случай (на самом деле, слава: p).
Foo const& fooForwarder(Foo const&); // out of line implementation which forwards
// the argument
Foo const& fooByVeryIndirectReference()
{
return fooForwarder(fooByValue());
}
Временная переменная, созданная fooByValue
, связана с временем жизни аргумента fooForwarder
, который должным образом предоставляет копию (ссылки), копию, которая возвращается вызывающей стороне, даже если она теперь указывает на эфир .
Проблема здесь в том, что реализация fooForwarder
прекрасно работает по отношению к стандарту, и все же она создает неопределенное поведение в вызывающей стороне.
Тем не менее, пугающим фактом является то, что для его диагностики необходимо знать о реализации fooForwarder
, недоступной для компилятора.
Единственное решение, которое я могу понять (кроме WPA), это решение во время выполнения: всякий раз, когда временное значение привязано к ссылке, необходимо убедиться, что возвращаемая ссылка не имеет один и тот же адрес ... и что потом ? assert
? поднять исключение? И поскольку это только решение времени выполнения, оно явно не удовлетворительное.
Идея привязки временного к ссылке хрупка.