§27.7.3.9
xác định tình trạng quá tải sau cho operator<<
:Tại sao quá tải rvalue của `toán tử <<` cho `basic_ostream` trả về một tham chiếu lvalue?
template <class charT, class traits, class T>
basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>&& os, const T& x);
Effects:
os << x
Returns:os
(§27.7.2.6
xác định tình trạng quá tải rvalue cho operator>>
.)
Về cơ bản, nó chỉ chuyển tiếp đến một quá tải lvalue. Tôi xem xét tình trạng quá tải này là khá nguy hiểm (các istream
một thậm chí nhiều hơn so với các ostream
một, trên thực tế), hãy xem xét những điều sau đây:
#include <sstream>
#include <iostream>
int main(){
auto& s = (std::stringstream() << "hi there!\n");
std::cout << s.rdbuf(); // oops
}
Live example on Ideone (ví dụ hoàn hảo của hành vi undefined Prints gì đối với tôi trên MSVC10.).
Ví dụ trên có thể trông giả tạo, nhưng nó không phải là quá khó khăn để có được vào tình trạng này trong mã chung hoặc khi đi qua các (std::stringstream() << "text")
đến một chức năng cung cấp một giá trị trái và một tình trạng quá tải rvalue và lưu trữ các std::ostream
hoặc std::istream
trong các cách khác nhau theo tình trạng quá tải.
Bây giờ, đối số sẽ lặp lại một số basic_ostream<charT, traits>&&
và chỉ định những điều sau đây là gì?
Returns: (. Và tương tự cho
basic_istream
) di chuyển (os)
Có điều gì tôi nhìn ra? Ở trạng thái hiện tại, trong mắt tôi, nó trông có vẻ nguy hiểm và giống như một khiếm khuyết. Tôi lướt qua số LWG issue list và tìm thấy this proposal (hi @HowardHinnant!). Nó thực sự trả về một rvalue, tuy nhiên chỉ vì lợi ích bổ sung của việc có thể chuỗi nhà điều hành đặc biệt này, không cụ thể giải quyết vấn đề an toàn tôi mô tả ở trên (mặc dù nó chắc chắn không giải quyết nó). Ngoài ra, nó được đánh dấu là đã đóng và xem xét lại cho tiêu chuẩn tiếp theo. Như vậy, tôi nghĩ rằng tôi muốn hỏi ở đây:
Có lý do chính đáng nào khiến quá tải nêu trên trả về tham chiếu lvalue không?
vì một lý do nào đó tất cả các MSVC tôi đã thấy dường như cho phép một liên kết giá trị với tham chiếu không phải const để trả về rvalue sẽ không thay đổi bất kỳ điều gì cho MSVS. –