std :: ostringstream打印c-string的地址而不是其内容 [英] std::ostringstream printing the address of the c-string instead of its content
问题描述
我偶然发现了一个我最初无法解释的怪异行为(请参阅 ideone ):
#include< iostream>
#include< sstream>
#include< string>
int main(){
std :: cout< 参考:
<< (void const *)some data
<< \\\
;
std :: ostringstream s;
s<< 一些数据;
std :: cout<< Regular Syntax:<< s.str()<< \\\
;
std :: ostringstream s2;
std :: cout<< Semi inline:
<< static_cast< std :: ostringstream&>(s2<某些数据)。str()
< \\\
;
std :: cout<< Inline:
<< dynamic_cast< std :: ostringstream&>(
std :: ostringstream()<<some data
).str()
& \\\
;
}
提供输出:
参考:0x804a03d
常规语法:一些数据
半内联:一些数据
内联:0x804a03d
令人惊讶的是,在最后一次演员中我们有地址,而不是内容!
为什么会这样?
解决方案表达式
std :: ostringstream()
创建一个临时,而作为参数的
const char *
的运算符<自由函数不能在临时对象上调用,因为函数的第一个参数的类型是
std :: ostream&
,它不能绑定到临时对象。
说的话,
<< std :: ostringstream()<< 一些数据
解析为对成员函数的调用,该函数重载用于打印地址的void *
。注意,可以在临时函数上调用成员函数。
为了调用自由函数,需要将临时变量(即右值)转换为左值,这里是一个你可以做的技巧:
std :: cout< Inline:
<< dynamic_cast< std :: ostringstream&>(
std :: ostringstream()。flush()).str()
< \\\
;
也就是说,
std :: ostringstream code>返回
std :: ostream&
这意味着,现在的free函数可以调用,传递返回的引用作为第一个参数。
此外,您不需要在这里使用
dynamic_cast
),对于类型的对象是众所周知的,所以你可以使用static_cast
(这是快速,因为它是在编译时完成):std :: cout< Inline:
<< static_cast< std :: ostringstream&>(
std :: ostringstream()。flush()<some data
).str()
< \\\
;
这应该可以正常工作。
I have stumbled on a weird behavior that I just could not explain at first (see 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"; }
Gives the output:
Reference : 0x804a03d Regular Syntax: some data Semi inline : some data Inline : 0x804a03d
Surprisingly, in the last cast we have the address, and not the content!
Why is that so ?
解决方案The expression
std::ostringstream()
creates a temporary, andoperator<<
which takesconst char*
as argument is a free function, but this free function cannot be called on a temporary, as the type of the first parameter of the function isstd::ostream&
which cannot be bound to temporary object.Having said that,
<<std::ostringstream() << "some data"
resolves to a call to a member function which is overloaded forvoid*
which prints the address. Note that a member function can be invoked on the temporary.In order to call the free function, you need to convert temporary (which is rvalue) into a lvalue, and here is one trick that you can do:
std::cout << "Inline : " << dynamic_cast<std::ostringstream&>( std::ostringstream().flush() << "some data" ).str() << "\n";
That is,
std::ostringstream().flush()
returnsstd::ostream&
which means, now the free function can called, passing the returned reference as first argument.Also, you don't need to use
dynamic_cast
here (which is slow, as it is done at runtime), for the type of the object is pretty much known, and so you can usestatic_cast
(which is fast as it is done at compile-time):std::cout << "Inline : " << static_cast<std::ostringstream&>( std::ostringstream().flush() << "some data" ).str() << "\n";
which should work just fine.
这篇关于std :: ostringstream打印c-string的地址而不是其内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!