À partir de cet article de blog Visual C ++ sur les références rvalue :
... C ++ ne veut pas que vous modifiiez accidentellement des temporaires, mais appeler directement une fonction membre non const sur une valeur r modifiable est explicite, donc c'est autorisé ...
Fondamentalement, vous ne devriez pas essayer de modifier les temporaires pour la simple raison qu'ils sont des objets temporaires et mourront à tout moment. La raison pour laquelle vous êtes autorisé à appeler des méthodes non const est que, bien, vous êtes invités à faire des choses "stupides" tant que vous savez ce que vous faites et que vous êtes explicite à ce sujet (comme, en utilisant reinterpret_cast). Mais si vous liez un temporaire à une référence non constante, vous pouvez continuer à le faire circuler "pour toujours" juste pour que votre manipulation de l'objet disparaisse, car quelque part en cours de route, vous avez complètement oublié que c'était un temporaire.
Si j'étais vous, je repenserais la conception de mes fonctions. Pourquoi g () accepte-t-il une référence, modifie-t-il le paramètre? Si non, faites-le const référence, si oui, pourquoi essayez-vous de lui passer un temporaire, ne vous souciez-vous pas que ce soit un temporaire que vous modifiez? Pourquoi getx () est-il de retour temporaire de toute façon? Si vous partagez avec nous votre scénario réel et ce que vous essayez d'accomplir, vous pouvez obtenir de bonnes suggestions sur la façon de le faire.
Aller à l'encontre du langage et tromper le compilateur résout rarement les problèmes - généralement cela crée des problèmes.
Edit: Répondre aux questions dans le commentaire: 1)
X& x = getx().ref(); // OK when will x die?
- Je ne sais pas et je m'en fiche, car c'est exactement ce que je veux dire par "aller à l'encontre de la langue". Le langage dit que "les temporaires meurent à la fin de la déclaration, à moins qu'ils ne soient obligés de const const, auquel cas ils meurent lorsque la référence sort du cadre". En appliquant cette règle, il semble que x soit déjà mort au début de l'instruction suivante, car il n'est pas lié à la référence const (le compilateur ne sait pas ce que ref () renvoie). Ce n'est qu'une supposition cependant.
2) J'ai clairement énoncé le but: vous n'êtes pas autorisé à modifier les temporaires, car cela n'a tout simplement pas de sens (en ignorant les références de valeur C ++ 0x). La question "alors pourquoi suis-je autorisé à appeler des membres non const?" est une bonne réponse, mais je n'ai pas de meilleure réponse que celle que j'ai déjà indiquée ci-dessus.
3) Eh bien, si j'ai raison à propos de x en X& x = getx().ref();
mourant à la fin de la déclaration, les problèmes sont évidents.
Quoi qu'il en soit, d'après votre question et vos commentaires, je ne pense pas que même ces réponses supplémentaires vous satisferont. Voici une dernière tentative / résumé: le comité C ++ a décidé qu'il n'était pas logique de modifier les temporaires, par conséquent, ils ont interdit la liaison à des références non const. Il peut y avoir une implémentation du compilateur ou des problèmes historiques ont également été impliqués, je ne sais pas. Ensuite, un cas spécifique a émergé, et il a été décidé que contre toute attente, ils permettraient toujours une modification directe en appelant la méthode non-const. Mais c'est une exception - vous n'êtes généralement pas autorisé à modifier les temporaires. Oui, C ++ est souvent aussi bizarre.