Я написал этот простой класс, который обеспечивает буферизацию для общей операции вывода:
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
?
EDIT
Я хотел бы использовать такую буферизацию для любого типа 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.)