Из этой статьи блога Visual C ++ о ссылках rvalue :
... C ++ не хочет, чтобы вы случайно модифицировали временные переменные, но прямой вызов неконстантной функции-члена для модифицируемого значения r является явным, так что это разрешено ...
По сути, вы не должны пытаться модифицировать временные объекты по той самой причине, что они являются временными объектами и теперь умирают в любой момент. Причина, по которой вам разрешено вызывать неконстантные методы, заключается в том, что вы можете делать некоторые «глупые» вещи, если вы знаете, что делаете, и вы явно об этом (например, используете reinterpret_cast). Но если вы привязываете временную ссылку к неконстантной ссылке, вы можете продолжать передавать ее «навсегда», просто чтобы ваши манипуляции с объектом исчезли, потому что где-то по пути вы полностью забыли, что это было временным.
Если бы я был тобой, я бы переосмыслил дизайн своих функций. Почему g () принимает ссылку, изменяет ли она параметр? Если нет, сделайте это константной ссылкой, если да, почему вы пытаетесь передать ему временный текст, не волнует ли это, что вы изменяете временный код? Почему getx () все равно возвращается временно? Если вы поделитесь с нами своим реальным сценарием и тем, что вы пытаетесь достичь, вы можете получить несколько хороших советов о том, как это сделать.
Идти против языка и дурачить компилятор редко решает проблемы - обычно это создает проблемы.
Изменить: Отвечая на вопросы в комментарии: 1)
X& x = getx().ref(); // OK when will x die?
- Я не знаю, и мне все равно, потому что это именно то, что я имею в виду под "идти против языка". Язык говорит: «Временные символы умирают в конце утверждения, если они не связаны с константной ссылкой, и в этом случае они умирают, когда ссылка выходит из области видимости». Применяя это правило, кажется, что x уже мертв в начале следующего оператора, так как он не связан с константной ссылкой (компилятор не знает, что возвращает ref ()). Это только предположение однако.
2) Я четко сформулировал цель: вам не разрешено изменять временные данные, потому что это просто не имеет смысла (игнорирование ссылок на значения C ++ 0x). Вопрос "тогда почему я могу звонить неконстантным участникам?" хороший, но у меня нет лучшего ответа, чем тот, который я уже сказал выше.
3) Ну, если я прав насчет х в X& x = getx().ref();
смерти в конце утверждения, проблемы очевидны.
В любом случае, основываясь на вашем вопросе и комментариях, я не думаю, что даже эти дополнительные ответы вас удовлетворит. Вот последняя попытка / краткое изложение: Комитет C ++ решил, что не имеет смысла изменять временные данные, поэтому они запретили привязку к неконстантным ссылкам. Может быть, некоторые реализации компилятора или исторические проблемы также были вовлечены, я не знаю. Затем возник какой-то конкретный случай, и было решено, что, несмотря ни на что, они по-прежнему допускают прямое изменение посредством вызова неконстантного метода. Но это исключение - вы, как правило, не можете изменять временные данные. Да, C ++ часто такой странный.