给定某种可流式传输的类型:
struct X {
int i;
friend std::ostream& operator<<(std::ostream& os, X const& x) {
return os << "X(" << x.i << ')';
}
};
我想将其附加到std::string
。我可以将其实现为:
void append(std::string& s, X const& x) {
std::ostringstream os;
os << x;
s.append(os.str());
}
但这似乎很蹩脚,因为我将数据写入一个流,然后分配一个新字符串,只是为了将其附加到另一个流上。有更直接的路线吗?
这可以通过一种新型的方法来解决streambuf https://gcc.gnu.org/onlinedocs/libstdc++/manual/streambufs.html (see 标准 C++ IOStream 和区域设置:高级程序员指南和参考 https://rads.stackoverflow.com/amzn/click/com/0321585585).
下面是它的外观草图:
#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.
}
};
一旦您充实了此处的详细信息,您就可以按如下方式使用它:
#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);
现在你只需写信给o
,结果应显示为附加到s
.
// This will append to s
o << 22;
Edit
正如 @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;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)