首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >输出c字符串的地址,而不是其内容

输出c字符串的地址,而不是其内容
EN

Stack Overflow用户
提问于 2011-11-28 00:48:58
回答 1查看 8K关注 0票数 19

我偶然发现了一种奇怪的行为,一开始我无法解释(参见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

令人惊讶的是,在最后的演员阵容中,我们有地址,而没有内容!

为什么会这样呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 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";

这应该可以很好地工作。

票数 19
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8287188

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档