std :: ostringstream打印c-string的地址而不是其内容 [英] std::ostringstream printing the address of the c-string instead of its content

查看:213
本文介绍了std :: ostringstream打印c-string的地址而不是其内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我偶然发现了一个我最初无法解释的怪异行为(请参阅 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 expressionstd::ostringstream() creates a temporary, and operator<< which takes const 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 is std::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 for void* 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() returns std::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 use static_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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆