在C ++中是否有缓冲输出操作的标准解决方案?

时间:2011-02-17 14:42:24

标签: c++ buffering

我编写了这个简单的类,为一般输出操作提供缓冲:

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数据类型。)

2 个答案:

答案 0 :(得分:3)

标准解决方案是子类std::streambuf,它是为您的任务设计的。有一些boost magic可以简化实施。

答案 1 :(得分:1)

cout默认是缓冲输出。你使用endl强制缓冲区刷新它的输出,但是你可以使用“\ n”intead。如果你的程序需要使用标志unitbuf,或者操纵器flush或endl并且你想避免刷新缓冲区,你可以使用一个特殊的流缓冲区,它不使用sync()来刷新流缓冲区,但我从来没有必要,所以我不清楚实施细节。