Давайте начнем с простого класса чтения сжатых файлов, используя boost::iostreams
:
class SingleFileOpener{
public:
SingleFileOpener(const std::string& filename, bool is_compressed) {
if(is_compressed) m_stream.push(bio::zlib_decompressor());
m_stream.push(bio::file_source{filename});
}
void print() {
bio::copy(m_stream, std::cout);
}
private:
using unseekable_stream = boost::iostreams::filtering_istream;
unseekable_stream m_stream;
};
Теперь вызов SingleFileOpener("input.txt", true)
с последующим print()
работает правильно. Coliru Link
Я хочу расширить свой класс для чтения и манипулирования несколькими файлами аналогичным образом.Ниже приведен пример кода, который я опробовал (закомментировано в ссылке Coliru выше):
class MultiFileOpener{
public:
MultiFileOpener(const std::vector<std::string> filenames, std::vector<bool> is_compressed) {
for(auto i = 0u; i < filenames.size(); i++) {
unseekable_stream s;
if(is_compressed[i]) s.push(bio::zlib_decompressor());
s.push(bio::file_source{filenames[i]});
m_stream.emplace_back(s); // <- error: use of deleted function(copy ctor)
}
}
void print(int i) {
bio::copy(*m_stream[i], std::cout);
}
private:
using unseekable_stream = boost::iostreams::filtering_istream;
std::vector<boost::optional<unseekable_stream>> m_stream;
};
Выше не компилируется из-за отсутствия конструкторов копирования в базовых классах.Я пытался использовать boost::optional
, std::shared_ptr
и другие альтернативы, используемые для отложенной инициализации.До сих пор единственное решение, которое сработало, это использование конструктора списка инициализатора для std::vector
, то есть выполнение ctor: m_stream(filenames.size()) {...}
.У меня было 2 вопроса:
- Почему здесь даже вызывается конструктор копирования?
- Возможно ли это сделать без списка инициализаторов?