我偶然发现了一种奇怪的行为,一开始我无法解释(参见ideone):
#include <iostream>
#include <sstream>
#include <string>
int main() {
std::cout << "Reference : "
<< (void const*)"some data"
<< "\n";
std::ostringstream s;
s << "some data";
std::cout << "Regular Syntax: " << s.str() << "\n";
std::ostringstream s2;
std::cout << "Semi inline : "
<< static_cast<std::ostringstream&>(s2 << "some data").str()
<< "\n";
std::cout << "Inline : "
<< dynamic_cast<std::ostringstream&>(
std::ostringstream() << "some data"
).str()
<< "\n";
}
给出输出:
Reference : 0x804a03d
Regular Syntax: some data
Semi inline : some data
Inline : 0x804a03d
令人惊讶的是,在最后的演员阵容中,我们有地址,而没有内容!
为什么会这样呢?
发布于 2011-11-28 00:54:46
表达式std::ostringstream()
创建一个临时函数,而以const char*
为参数的operator<<
是一个自由函数,但是这个自由函数不能在临时对象上调用,因为该函数的第一个参数的类型是std::ostream&
,它不能绑定到临时对象。
话虽如此,<<std::ostringstream() << "some data"
解析为对成员函数的调用,该成员函数对于打印地址的void*
来说是重载的。注意,成员函数可以在临时调用。
为了调用free函数,您需要将临时(这是rvalue)转换为lvalue,下面是您可以做的一个技巧:
std::cout << "Inline : "
<< dynamic_cast<std::ostringstream&>(
std::ostringstream().flush() << "some data"
).str()
<< "\n";
也就是说,std::ostringstream().flush()
返回std::ostream&
,这意味着现在可以调用自由函数,将返回的引用作为第一个参数进行传递。
此外,您不需要在这里使用dynamic_cast
(这很慢,因为它是在运行时完成的),因为对象的类型是非常已知的,所以您可以使用static_cast
(它在编译时完成得很快):
std::cout << "Inline : "
<< static_cast<std::ostringstream&>(
std::ostringstream().flush() << "some data"
).str()
<< "\n";
这应该可以很好地工作。
https://stackoverflow.com/questions/8287188
复制相似问题