Từ bài viết trên blog Visual C ++ này về các tài liệu tham khảo về giá trị :
... C ++ không muốn bạn vô tình sửa đổi tạm thời, nhưng gọi trực tiếp một hàm không phải thành viên theo giá trị có thể sửa đổi là rõ ràng, vì vậy nó được phép ...
Về cơ bản, bạn không nên cố gắng sửa đổi tạm thời vì lý do chúng là đối tượng tạm thời và sẽ chết bất cứ lúc nào. Lý do bạn được phép gọi các phương thức không phải là vì, tốt, bạn được hoan nghênh làm một số điều "ngu ngốc" miễn là bạn biết bạn đang làm gì và bạn rõ ràng về nó (như, sử dụng reinterpret_cast). Nhưng nếu bạn liên kết tạm thời với một tham chiếu không phải là const, bạn có thể tiếp tục chuyển nó xung quanh "mãi mãi" chỉ để thao tác của đối tượng biến mất, bởi vì ở đâu đó trên đường bạn hoàn toàn quên mất đây là tạm thời.
Nếu tôi là bạn, tôi sẽ suy nghĩ lại về thiết kế các chức năng của mình. Tại sao g () chấp nhận tham chiếu, nó có sửa đổi tham số không? Nếu không, làm cho nó là tham chiếu, nếu có, tại sao bạn cố gắng chuyển tạm thời cho nó, bạn không quan tâm đó là tạm thời bạn đang sửa đổi? Tại sao getx () trở lại tạm thời? Nếu bạn chia sẻ với chúng tôi kịch bản thực sự của bạn và những gì bạn đang cố gắng thực hiện, bạn có thể nhận được một số đề xuất tốt về cách thực hiện.
Đi ngược lại với ngôn ngữ và đánh lừa trình biên dịch hiếm khi giải quyết vấn đề - thông thường nó tạo ra vấn đề.
Chỉnh sửa: Giải quyết các câu hỏi trong nhận xét: 1)
X& x = getx().ref(); // OK when will x die?
- Tôi không biết và tôi không quan tâm, bởi vì đây chính xác là những gì tôi muốn nói là "đi ngược lại ngôn ngữ". Ngôn ngữ nói "tạm thời chết ở cuối câu lệnh, trừ khi chúng bị ràng buộc với tham chiếu const, trong trường hợp chúng chết khi tham chiếu vượt quá phạm vi". Áp dụng quy tắc đó, có vẻ như x đã chết ở đầu câu lệnh tiếp theo, vì nó không bị ràng buộc với tham chiếu const (trình biên dịch không biết ref () trả về cái gì). Đây chỉ là một phỏng đoán.
2) Tôi đã nêu rõ mục đích: bạn không được phép sửa đổi tạm thời, vì nó chỉ không có ý nghĩa (bỏ qua các tham chiếu giá trị C ++ 0x). Câu hỏi "tại sao tôi được phép gọi các thành viên không phải là const?" là một câu hỏi hay, nhưng tôi không có câu trả lời tốt hơn câu tôi đã nêu ở trên.
3) Chà, nếu tôi đúng về x khi X& x = getx().ref();
chết ở cuối bản tuyên bố, thì vấn đề là rõ ràng.
Dù sao, dựa trên câu hỏi và nhận xét của bạn, tôi không nghĩ ngay cả những câu trả lời bổ sung này cũng sẽ làm bạn hài lòng. Đây là một nỗ lực / tóm tắt cuối cùng: Ủy ban C ++ đã quyết định không sửa đổi thời gian, do đó, họ không cho phép ràng buộc với các tham chiếu không liên tục. Có thể một số triển khai trình biên dịch hoặc các vấn đề lịch sử cũng có liên quan, tôi không biết. Sau đó, một số trường hợp cụ thể đã xuất hiện và đã quyết định rằng chống lại tất cả các tỷ lệ cược, họ vẫn sẽ cho phép sửa đổi trực tiếp thông qua việc gọi phương thức không phải là const. Nhưng đó là một ngoại lệ - bạn thường không được phép sửa đổi tạm thời. Vâng, C ++ thường kỳ lạ.