Da questo articolo del blog di Visual C ++ sui riferimenti ai valori :
... C ++ non vuole che tu modifichi accidentalmente i provvisori, ma chiamare direttamente una funzione membro non const su un valore modificabile è esplicito, quindi è permesso ...
Fondamentalmente, non dovresti provare a modificare i provvisori proprio perché sono oggetti temporanei e moriranno da un momento all'altro. Il motivo per cui ti è permesso chiamare metodi non costanti è che, beh, sei il benvenuto a fare alcune cose "stupide" fintanto che sai cosa stai facendo e ne sei esplicito (come usare reinterpret_cast). Ma se associ un temporaneo a un riferimento non const, puoi continuare a passarlo "per sempre" solo per far scomparire la tua manipolazione dell'oggetto, perché da qualche parte lungo la strada hai completamente dimenticato che si trattava di un temporaneo.
Se fossi in te, ripenserei al design delle mie funzioni. Perché g () accetta il riferimento, modifica il parametro? Se no, rendilo riferimento costante, se sì, perché provi a passargli temporaneamente, non ti importa che sia un temporaneo che stai modificando? Perché getx () torna comunque temporaneo? Se condividi con noi il tuo scenario reale e ciò che stai cercando di realizzare, potresti ricevere alcuni buoni suggerimenti su come farlo.
Andare contro il linguaggio e ingannare il compilatore raramente risolve i problemi - di solito crea problemi.
Modifica: rispondere alle domande nel commento: 1)
X& x = getx().ref(); // OK when will x die?
- Non lo so e non mi interessa, perché questo è esattamente ciò che intendo per "andare contro la lingua". La lingua dice "i provvisori muoiono alla fine dell'affermazione, a meno che non siano vincolati al riferimento const, nel qual caso muoiono quando il riferimento va oltre lo scopo". Applicando quella regola, sembra che x sia già morto all'inizio dell'istruzione successiva, poiché non è legato al riferimento const (il compilatore non sa cosa restituisce ref ()). Questa è solo una supposizione però.
2) Ho dichiarato chiaramente lo scopo: non è consentito modificare i provvisori, perché non ha senso (ignorando i riferimenti al valore C ++ 0x). La domanda "allora perché mi è permesso chiamare membri non const?" è buono, ma non ho una risposta migliore di quella che ho già affermato sopra.
3) Beh, se ho ragione x X& x = getx().ref();
morire alla fine della frase, i problemi sono evidenti.
Ad ogni modo, in base alla tua domanda e ai tuoi commenti, non penso che nemmeno queste risposte extra ti possano soddisfare. Ecco un ultimo tentativo / riassunto: il comitato C ++ ha deciso che non ha senso modificare i provvisori, pertanto non ha consentito il legame con riferimenti non costanti. Potrebbe essere l'implementazione di un compilatore o sono stati coinvolti anche problemi storici, non lo so. Quindi, è emerso un caso specifico ed è stato deciso che, nonostante ogni previsione, consentiranno comunque la modifica diretta tramite la chiamata del metodo non const. Ma questa è un'eccezione: in genere non ti è consentito modificare i provvisori. Sì, il C ++ è spesso così strano.