c++ - cout 一个 stringstream 但打印一个指针

标签 c++ c++03

这是我的代码:

#include <iostream>
#include <sstream>
#include <string>

using namespace std;

class TestLog: public std::stringstream
{
        public:
                ~TestLog()
                {
                        cout << (str()) << endl; // Why does this print an address ?
                }
};

int main()
{
        TestLog() << "Hello World!"; //test 1 print an address
        stringstream ss;
        ss << "Hello World!";
        cout << (ss.str()) << endl; //test 2 print a string

        return 0;
}

输出:

0x401b90

Hello World!

编译器信息:

g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-11)

在我看来, (a) std::stringstream 的 str() 方法返回一个字符串。 (b)std::cout 是 std::ostream 的对象。 因此,这两个测试都将调用 ostream 的相同运算符函数并打印相同的“Hello world”。 但是测试 1 打印地址,测试 2 打印正确的“Hello world”。
我怎么了 ?谢谢。

最佳答案

ss << "Hello World!";解析为对以下重载 ( #2 on this page ) 的调用:

template <class Traits>
std::basic_ostream<char, Traits> &std::operator << (
    std::basic_ostream<char, Traits> &os, char const *s
);

此重载将字符串文字衰减为 char const * , 然后打印出来。

要搅动泥浆,我们可以尝试以下代码片段:

TestLog tl;
tl << "Hello World!";

这个将解析到上面的重载,并打印 Hello World! .那是因为 tl是一个左值,它可以绑定(bind)到非 const 的第一个参数左值引用。

在您的示例中,TestLog()是一个右值——这个重载不能匹配!因此选择了另一个重载(#7 here):

std::basic_ostream &std::basic_ostream::operator << (void const *value);

这是一个成员函数重载,继承自std::stringstream .即使您不能绑定(bind)非 const引用右值,您可以调用非 const右值的成员函数。所以这个重载是一个有效的匹配,它被选中——打印文字的地址,就好像它是任何旧指针一样。

C++11 带来了一个新的重载来解决这个问题,可见于 #3 here :

template <class CharT, class Traits, class T>
std::basic_ostream<CharT, Traits> &operator << (
    basic_ostream<CharT, Traits> &&os, T const &value
);

T const &匹配文字的 char const[N]打字完美,因此它的排名高于 void const *重载。作为第一个参数的右值引用绑定(bind)到临时变量就好了。

命名的右值引用被认为是左值,所以这个函数可以调用 os << value;再次蹦床回到左值流的重载集。因此,在 C++11 及更高版本中,两行都打印出 Hello World!。 .

关于c++ - cout 一个 stringstream 但打印一个指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41425325/

相关文章:

c++ - 反向传播不适用于 XOR

c++ - 使用 CRTP 和多重继承消除冗余

c++ - 将 std::vector<int> 保存到文件

c++ - 用模板替换 boost::function 和 boost::bind

c++ - 在 C++ 中使用类模板作为回调

c++ - 有没有更有效的方法来原子地添加两个 float ?

c++ - 防止兄弟结构的平等比较

Python C API bool 对象

c++ - CUDA __host__ __device__ 变量

c++ - C++11 何时进行相对于运算符优先级的算术类型转换?