Из этого Статья в блоге Visual C ++ о ссылках на rvalue:
... C ++ не хочет, чтобы вы случайно изменили временные файлы, но прямой вызов неконстантной функции-члена для изменяемого rvalue является явным, поэтому он разрешен ...
По сути, вы не должны пытаться модифицировать временные объекты именно по той причине, что они являются временными объектами и умрут в любой момент. Причина, по которой вам разрешено вызывать неконстантные методы, заключается в том, что вы можете делать некоторые «глупые» вещи, если вы знаете, что делаете, и четко указываете на это (например, используя reinterpret_cast). Но если вы привяжете временную ссылку к неконстантной ссылке, вы можете продолжать передавать ее «вечно» просто для того, чтобы ваши манипуляции с объектом исчезли, потому что где-то по пути вы полностью забыли, что это было временным.
На вашем месте я бы переосмыслил дизайн своих функций. Почему g () принимает ссылку, изменяет ли он параметр? Если нет, сделайте это константной ссылкой, если да, то почему вы пытаетесь передать ему временное значение, разве вас не волнует, что это временное значение, которое вы изменяете? Почему getx () все равно возвращается временно? Если вы поделитесь с нами своим реальным сценарием и тем, чего вы пытаетесь достичь, вы можете получить несколько хороших советов о том, как это сделать.
Противодействие языку и обман компилятора редко решают проблемы - обычно они создают проблемы.
Изменить: ответы на вопросы в комментариях: 1)
X& x = getx().ref(); // OK when will x die?
- Я не знаю и мне все равно, потому что это именно то, что я имею в виду, говоря «идти против языка». В языке говорится, что «временные объекты умирают в конце оператора, если они не привязаны к константной ссылке, и в этом случае они умирают, когда ссылка выходит за пределы области видимости». Применяя это правило, кажется, что x уже мертв в начале следующего оператора, поскольку он не привязан к ссылке const (компилятор не знает, что возвращает ref ()). Однако это всего лишь предположение.
2) Я четко сформулировал цель: вам не разрешено изменять временные файлы, потому что это просто не имеет смысла (игнорируя ссылки C ++ 0x rvalue). На вопрос «тогда почему мне разрешено вызывать неконстантные члены?» хороший, но у меня нет лучшего ответа, чем тот, который я уже сказал выше.
3) Что ж, если я прав насчет x in X& x = getx().ref();
dying в конце утверждения, проблемы очевидны.
В любом случае, судя по вашему вопросу и комментариям, я не думаю, что даже эти дополнительные ответы вас удовлетворит. Вот последняя попытка / резюме: комитет C ++ решил, что нет смысла изменять временные файлы, поэтому они запретили привязку к неконстантным ссылкам. Может быть, была задействована какая-то реализация компилятора или исторические проблемы, я не знаю. Затем возник какой-то конкретный случай, и было решено, что, несмотря ни на что, они все же разрешат прямую модификацию через вызов неконстантного метода. Но это исключение - вам обычно не разрешается изменять временные файлы. Да, C ++ часто бывает таким странным.
person
sbk
schedule
14.10.2009
/W4
или/Wall
компилятор выдает предупреждение:C4239: nonstandard extension used: 'argument': conversion from 'type' to 'type&'
. При отключении языковых расширений/Za
он не работает сerror C2664: cannot convert argument 1 from 'type' to 'type&'
- person Ivan Aksamentov - Drop   schedule 11.06.2015