将对象直接流入std :: string

Bar*_*rry 21 c++ string

给定一些可流式的类型:

struct X {
    int i;

    friend std::ostream& operator<<(std::ostream& os, X const& x) {
        return os << "X(" << x.i << ')';
    }
};
Run Code Online (Sandbox Code Playgroud)

我想把它添加到一个std::string.我可以这样实现:

void append(std::string& s, X const& x) {
    std::ostringstream os;
    os << x;
    s.append(os.str());
}
Run Code Online (Sandbox Code Playgroud)

但这似乎很蹩脚,因为我正在将数据写入一个流,然后为了将其附加到另一个流上而分配一个新的字符串.有更直接的路线吗?

Ami*_*ory 15

这可以通过一种新类型来解决streambuf(参见标准C++ IOStreams和Locales:高级程序员指南和参考).

这是一个如何看的草图:

#include <streambuf>

class existing_string_buf : public std::streambuf
{
public:
    // Store a pointer to to_append.
    explicit existing_string_buf(std::string &to_append); 

    virtual int_type overflow (int_type c) {
        // Push here to the string to_append.
    }
};
Run Code Online (Sandbox Code Playgroud)

一旦你在这里充实了细节,你可以按如下方式使用它:

#include <iostream>

std::string s;
// Create a streambuf of the string s
existing_string_buf b(s);
// Create an ostream with the streambuf
std::ostream o(&b);
Run Code Online (Sandbox Code Playgroud)

现在你只需要写入o,结果应该显示为附加到s.

// This will append to s
o << 22;
Run Code Online (Sandbox Code Playgroud)

编辑

正如@rustyx正确指出的那样,xsputn需要重写以提高性能.

完整的例子

以下打印件22:

#include <streambuf>
#include <string>
#include <ostream> 
#include <iostream>

class existing_string_buf : public std::streambuf
{
public:
    // Somehow store a pointer to to_append.
    explicit existing_string_buf(std::string &to_append) : 
        m_to_append(&to_append){}

    virtual int_type overflow (int_type c) {
        if (c != EOF) {
            m_to_append->push_back(c);
        }
        return c;
    }

    virtual std::streamsize xsputn (const char* s, std::streamsize n) {
        m_to_append->insert(m_to_append->end(), s, s + n);                                                                                 
        return n;
    }

private:
    std::string *m_to_append;
};


int main()
{   
    std::string s;
    existing_string_buf b(s);
    std::ostream o(&b);

    o << 22; 

    std::cout << s << std::endl;
}   
Run Code Online (Sandbox Code Playgroud)

  • 有时我觉得我懂C++.这不是其中之一. (4认同)
  • 我还会覆盖`xsputn()`以获得良好的性能. (3认同)