【问题标题】:Printing Stringstream Outputs Pointer打印字符串流输出指针
【发布时间】:2011-09-17 23:27:52
【问题描述】:

下面的代码不是输出预期的字符串"Bar",而是输出一个看起来像指针的东西。

#include <sstream>
#include <iostream>

int main()
{
    std::stringstream Foo("Bar");
    std::cout << Foo << std::endl; // Outputs "0x22fe80."
    return 0;
}

这可以通过使用Foo.str() 来解决,但它在过去给我造成了一些问题。是什么导致了这种奇怪的行为?它记录在哪里?

【问题讨论】:

  • 既然已经回答了,我不妨把地址的含义放在这里,以防你好奇。通常,为了允许在布尔上下文中测试流,运算符 void* 被重载,这会导致(在某些实现中)像operator void *() const {return (fail() ? 0 : (void *)this);} 这样的代码(如果没有设置失败标志)将返回对象本身的地址。在某些实现中,这意味着类成员或虚拟表指针的地址,至少在 vc++ 中似乎是后者。

标签: c++ pointers implicit-conversion stringstream


【解决方案1】:

std::stringstream 不应该插入到流中。这就是你有str() 方法的原因。

您观察到的行为是因为 std::stringstream 转换为 void*,这是用于测试流的:

if(Foo) { // this uses the conversion to void*
}

在 C++11 中,此转换被显式转换为 bool 所取代,这会导致此代码无法编译:

std::cout << Foo << std::endl;

【讨论】:

  • 为什么不能编译?不就是输出1什么的吗?
  • 不,因为转换是明确的,这意味着你必须写std::cout &lt;&lt; bool(Foo);。查看其他答案以获取更多信息:stackoverflow.com/questions/6242296/…
【解决方案2】:

(1)使用 std::cout

(2)如果没有重载 "

【讨论】:

    【解决方案3】:

    这可以通过使用 Foo.str() 来解决,但它在过去给我带来了一些问题。是什么导致了这种奇怪的行为?它记录在哪里?

    一点都不奇怪。

    流是流,而不是字符串。

    您可以通过成员函数.str() 获取[string] 缓冲区。这不是解决方法:它是 API。它应该记录在您的 C++ 标准库参考中,如果不是,则说明您的参考不完整/错误。

    ( 有点奇怪的是你得到的是内存地址而不是编译错误;那是由于在 pre- C++0x 标准库,如另一个答案所述。)

    【讨论】:

    • 嗯,这是真正的 safe bool 习语。更像是某种残缺的形式......
    • @Xeo:好吧,随便。至少是模糊的相关。 :) 认为我的答案的那部分是不规范的!
    • @Xeo:它仍然比 C++03 中的 operator bool 更安全 :)
    • 将其打包在[ Note: ... -end note ] 中。 ;)
    • @Xeo:我几乎做到了,但是 5 分钟的窗口已经过去,我不希望我的答案出现编辑:P
    猜你喜欢
    • 2023-03-15
    • 2018-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-01
    • 2021-12-05
    • 1970-01-01
    相关资源
    最近更新 更多