我编写了这个简单的类,为一般输出操作提供缓冲:
template <typename T>
class WriteBuffer {
typedef void (&flush_t)(const T* values, const size_t size);
public:
WriteBuffer(size_t size, flush_t flush) : flush_(flush) {
v_.reserve(size);
}
~WriteBuffer() { flush(); }
void flush() {
if (v_.size() > 0) {
flush_(&v_[0], v_.size());
v_.clear();
}
}
void write(const T value) {
if (v_.size() == v_.capacity())
flush();
v_.push_back(value);
}
private:
vector<T> v_;
flush_t flush_;
};
(为简单起见,省略了错误检查。)以下示例程序:
void writeInt(const int* values, const size_t size) {
cout << "Writing buffer of size " << size << ": " << endl;
for (size_t i = 0; i < size; ++i)
cout << values[i] << ", ";
cout << endl;
}
int main(int argc, char* argv[]) {
WriteBuffer<int> buffer(5, writeInt);
for (size_t i = 0; i < 18; ++i)
buffer.write(i);
return 0;
}
然后生成以下输出:
Writing buffer of size 5: 0, 1, 2, 3, 4, Writing buffer of size 5: 5, 6, 7, 8, 9, Writing buffer of size 5: 10, 11, 12, 13, 14, Writing buffer of size 3: 15, 16, 17,
是否存在此问题的任何标准/更好的解决方案,例如一些具有类似功能的STL容器/ BOOST类?谢谢!
其他问题:您更喜欢使用函数对象而不是函数引用flush_t
吗?
我想对客户端提供的任何类型T
和任何flush
操作使用此类缓冲(不仅仅是字符和输出流)。例如:
template <typename T>
void write(const T* values, const size_t size) {
...
H5Dwrite(..., values);
...
}
WriteBuffer<unsigned long> buffer(8192, write<unsigned long>);
将数据写入HDF5数据集。 (这里没有解决HDF5数据类型。)
答案 0 :(得分:3)
标准解决方案是子类std::streambuf
,它是为您的任务设计的。有一些boost
magic可以简化实施。
答案 1 :(得分:1)
cout默认是缓冲输出。你使用endl强制缓冲区刷新它的输出,但是你可以使用“\ n”intead。如果你的程序需要使用标志unitbuf,或者操纵器flush或endl并且你想避免刷新缓冲区,你可以使用一个特殊的流缓冲区,它不使用sync()来刷新流缓冲区,但我从来没有必要,所以我不清楚实施细节。