Чтобы отклонить ваш первый фрагмент кода, компилятор применяет простое правило, согласно которому вы не можете напрямую привязать временную ссылку к неконстантной ссылке.
Чтобы отклонить вторую, компилятор может применить правило, чтоreturn
оператор функции, которая возвращается по ссылке, не может быть именем автоматической переменной (включая параметр функции по значению).Это тоже кажется мне довольно простым правилом.
Я не знаю, почему в стандарте не указано, что это неправильно.Я не могу думать о каком-либо действительном использовании для него, но, возможно, во время первого стандарта это создало бы чрезмерную нагрузку на ту или иную реализацию.Или, может быть, чувствовалось, что это только половина исправления, и его не стоит беспокоить (есть множество других способов создать висячую ссылку, это просто блокирует один из них).
Причина, по которой стандарт не делаетв общем, остановите создание неконстантной ссылки, привязанной к временной, в тех случаях, когда это нормально.Например:
struct Foo {
static void set(Foo &f) { f.val = 0; }
int val;
int bar() {
set(*this);
return val;
}
};
std::cout << Foo().bar() << "\n";
Здесь Foo()
является временным, и строка set(*this)
связывает его с неконстантной ссылкой (но не напрямую, она использует выражение lvalue *this
, которое относится квременные несколько раз, но не другие).Здесь нет проблем, временные ссылки отживают.Поэтому для языка было бы излишне ограничительным каким-либо образом предотвращать привязку любого временного к какой-либо неконстантной ссылке.