Xeo*_*Xeo 24 c++ iostream rvalue-reference c++11
§27.7.3.9
为以下内容定义以下重载operator<<
:
template <class charT, class traits, class T>
basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>&& os, const T& x);
Run Code Online (Sandbox Code Playgroud)
效果:
os << x
退货:os
(§27.7.2.6
定义rvalue重载operator>>
.)
基本上,它只是转发到左值超载.我认为这个重载非常危险(实际上istream
比ostream
实际更重要),请考虑以下内容:
#include <sstream>
#include <iostream>
int main(){
auto& s = (std::stringstream() << "hi there!\n");
std::cout << s.rdbuf(); // oops
}
Run Code Online (Sandbox Code Playgroud)
关于Ideone的实例(未定义行为的完美示例.在MSVC10上没有为我打印).
上面的例子看起来做作,但它不应该太难进入这个情况在通用代码或传递时(std::stringstream() << "text")
,以提供一个左值和一个右值过载和存储功能std::ostream
或std::istream
以不同的方式根据过载.
现在,又将返回a basic_ostream<charT, traits>&&
并指定以下内容的参数是什么?
返回: move(os)
(同样的basic_istream
.)
有什么我可以忽略的吗?在目前的状态,在我看来,它看起来很危险,就像一个缺陷.我浏览了LWG问题列表并找到了这个提议(嗨@HowardHinnant!).它确实会返回一个右值,但是只为能够链这个特殊的运营商,而不是专门针对我上面描述的安全问题(尽管它肯定是额外的好处,确实解决它).此外,它被标记为关闭并重新考虑下一个标准.因此,我想我会在这里问:
上面提到的重载返回左值引用有什么好的理由吗?
How*_*ant 15
这是一个缺陷,这是我的错,抱歉. LWG 1203(感谢为我找到!:-))是我目前对"rvalue-stream-inserter"正确修复的看法.请注意,你仍然可以抓住它并遇到麻烦:
auto&& s = (std::stringstream() << "hi there!\n");
std::cout << s.rdbuf(); // oops
Run Code Online (Sandbox Code Playgroud)
虽然至少在上面的代码中&&
,你做一些你不应该做的事情更明显(因为).