我想要一个用于写入自动调整大小数组的接口.一种方法是使用通用std::ostream *.
然后考虑ostringstream是否是目标:
void WritePNG(ostream *out, const uint8_t *pixels); void *WritePNGToMemory(uint8_t *pixels) { ostringstream out; WritePng(&out, pixels); uint8_t *copy = new uint8_t[out.tellp()]; memcpy(copy, out.str().c_str(), out.tellp()]; return copy; }但是我想避免使用memcpy().有没有办法在底层的stringbuf类中获取数组的所有权并将其返回?
我感到无法使用标准库完成此操作,因为流缓冲区甚至可能不是连续数组.
解决方案IIRC字符串流存在的原因(与strstream相比)是为了解决内存所有权的模糊问题,这些问题将通过直接缓冲区访问而出现.例如我认为更改是为了明确阻止您要执行的操作.
我认为您必须自己通过覆盖流缓冲区来做到这一点.为了回答类似的问题,我为输入流提出了一些建议,这些建议最终获得了很多好评.但说实话,我当时当时还不知道我在说什么,
通过此网络链接进行高位流缓冲区",只是回显并为您提供对其缓冲区的引用可能会给出:
#include <iostream> #include <streambuf> class outbuf : public std::streambuf { std::string data; protected: virtual int_type overflow (int_type c) { if (c != EOF) data.push_back(c); return c; } public: std::string& get_contents() { return data; } }; int main() { outbuf ob; std::ostream out(&ob); out << "some stuff"; std::string& data = ob.get_contents(); std::cout << data; return 0; }我确信它以各种方式被破坏了.但是大写缓冲区的作者似乎认为,单独重写overflow()方法会让他们将所有输出大写为流,因此我猜可能会争辩说,如果写一个自己的缓冲区就足以看到所有输出. >
但是,即使这样,一次执行一个字符似乎不是最佳选择……而且谁知道从一开始就从streambuf继承会带来什么样的开销. 请咨询您最近的C ++ iostream专家,以了解正确的正确方法.但希望它证明了某种可能性.
I'd like an interface for writing to an automatically resizing array. One way to do this is with a generic std::ostream *.
Then consider if ostringstream is the target:
void WritePNG(ostream *out, const uint8_t *pixels); void *WritePNGToMemory(uint8_t *pixels) { ostringstream out; WritePng(&out, pixels); uint8_t *copy = new uint8_t[out.tellp()]; memcpy(copy, out.str().c_str(), out.tellp()]; return copy; }But I want to avoid the memcpy(). Is there a way to take ownership of the array in the underlying stringbuf class and return that?
I get the feeling this can't be done using standard library, since the stream buffer might not even be a contiguous array.
解决方案IIRC the whole reason stringstream exists (vs strstream) was to sort out the fuzzy questions of memory ownership that would come up by giving direct buffer access. e.g. I think that change was to specifically prevent what you are asking to do.
One way or another I think you'd have to do it yourself, by overriding the stream buffer. To answer a similar question I suggested something for input streams that wound up getting quite a few upvotes. But honestly I didn't know what I was talking about then, nor now when I suggest the following:
Hacking up this link from the web for doing an "uppercasing stream buffer" to one that just echoes and gives you a reference to its buffer might give:
#include <iostream> #include <streambuf> class outbuf : public std::streambuf { std::string data; protected: virtual int_type overflow (int_type c) { if (c != EOF) data.push_back(c); return c; } public: std::string& get_contents() { return data; } }; int main() { outbuf ob; std::ostream out(&ob); out << "some stuff"; std::string& data = ob.get_contents(); std::cout << data; return 0; }I'm sure it's broken in all kinds of ways. But the uppercase-buffer-authors seemed to think that overriding the overflow() method alone would let them uppercase all output to the stream, so I guess one could argue that it's enough to see all output if writing to one's own buffer.
But even so, going one character at a time seems suboptimal...and who knows what overhead you get from inheriting from streambuf in the first place. Consult your nearest C++ iostream expert for what the actual right way is. But hopefully it's proof that something of the sort is possible.
更多推荐
取得streambuf/stringbuf数据的所有权
发布评论