Dari artikel blog Visual C ++ ini tentang referensi nilai :
... C ++ tidak ingin Anda memodifikasi temporer secara tidak sengaja, tetapi langsung memanggil fungsi non-const member pada nilai yang dapat dimodifikasi adalah eksplisit, jadi diizinkan ...
Pada dasarnya, Anda tidak boleh mencoba mengubah temporari karena alasan mereka temporer dan akan mati kapan saja sekarang. Alasan Anda diizinkan memanggil metode non-const adalah karena, Anda boleh melakukan beberapa hal "bodoh" selama Anda tahu apa yang Anda lakukan dan Anda eksplisit tentang hal itu (seperti, menggunakan reinterpret_cast). Tetapi jika Anda mengikat sementara ke referensi non-const, Anda bisa terus menyebarkannya "selamanya" hanya untuk menghilangkan manipulasi objek, karena di suatu tempat di mana Anda benar-benar lupa ini adalah sementara.
Jika saya jadi Anda, saya akan memikirkan kembali desain fungsi saya. Mengapa g () menerima referensi, apakah itu memodifikasi parameter? Jika tidak, buatlah itu sebagai referensi, jika ya, mengapa Anda mencoba memberikan sementara untuk itu, tidakkah Anda peduli itu hanya sementara yang Anda modifikasi? Kenapa getx () kembali sementara? Jika Anda berbagi dengan kami skenario nyata Anda dan apa yang ingin Anda capai, Anda mungkin mendapatkan beberapa saran bagus tentang bagaimana melakukannya.
Melawan bahasa dan menipu kompiler jarang memecahkan masalah - biasanya itu menciptakan masalah.
Sunting: Mengatasi pertanyaan dalam komentar: 1)
X& x = getx().ref(); // OK when will x die?
- Saya tidak tahu dan saya tidak peduli, karena inilah yang saya maksud dengan "menentang bahasa". Bahasa mengatakan "temporaries mati pada akhir pernyataan, kecuali mereka terikat dengan referensi konstan, dalam hal ini mereka mati ketika referensi keluar dari ruang lingkup". Menerapkan aturan itu, tampaknya x sudah mati di awal pernyataan berikutnya, karena itu tidak terikat dengan referensi const (kompiler tidak tahu apa yang ref () kembali). Namun ini hanya dugaan saja.
2) Saya menyatakan tujuannya dengan jelas: Anda tidak diperbolehkan untuk mengubah temporaries, karena itu tidak masuk akal (mengabaikan nilai rujukan C ++ 0x). Pertanyaannya "lalu mengapa saya diizinkan memanggil anggota non-const?" adalah jawaban yang bagus, tetapi saya tidak memiliki jawaban yang lebih baik daripada jawaban yang telah saya sebutkan di atas.
3) Nah, jika saya benar tentang x dalam X& x = getx().ref();
sekarat di akhir pernyataan, masalahnya jelas.
Ngomong-ngomong, berdasarkan pertanyaan dan komentar Anda, saya rasa jawaban ekstra ini tidak akan memuaskan Anda. Berikut ini adalah upaya / ringkasan terakhir: Komite C ++ memutuskan tidak masuk akal untuk mengubah temporari, oleh karena itu, mereka melarang pengikatan pada referensi non-const. Mungkin beberapa implementasi kompiler atau masalah bersejarah juga terlibat, saya tidak tahu. Kemudian, beberapa kasus spesifik muncul, dan diputuskan bahwa melawan segala rintangan, mereka masih akan memungkinkan modifikasi langsung melalui pemanggilan metode non-const. Tapi itu pengecualian - Anda biasanya tidak diizinkan mengubah temporer. Ya, C ++ seringkali aneh.