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