使用istream_iterator构造自定义类型的向量

时间:2016-11-26 21:14:11

标签: c++ serialization stl fstream stdvector

我想编写并读取我的类类型的STL Vector到二进制文件,但是不明白istream_iterator有什么问题。
项目规则不允许使用文本文件, 与Boost等第三方库相同。

这是Book.h:

void writeBook(std::vector<Book> books) {
    std::ofstream binOut("book.bin", std::ios::binary);
    std::copy(books.begin(), books.end(),
        std::ostream_iterator<Book>(binOut, "\n")); 
}

这是写方法:

std::vector<Book> readBooks() {
    std::vector<Book> toReturn;
    std::ifstream BinIn("book.bin", std::ios::binary);
    std::istream_iterator<Book> file_iter(BinIn);
    std::istream_iterator<Book> end_of_stream;
    std::copy(file_iter, end_of_stream, std::back_inserter(toReturn));
    return toReturn;    
}

我想这样读:

{{1}}

Compiller说 - Book:没有合适的默认构造函数。

1 个答案:

答案 0 :(得分:3)

std::istream_iterator<Book>使用operator>>(std::istream&, Book&)将数据读入对象。由于此operator>>需要将现有Book对象作为参数(将数据写入),因此迭代器必须先构造一个,然后才能将数据从流中转储到其中,为此需要默认构造函数。

您的Book班级没有。解决问题的最简单方法是给它一个。

如果这不是一个选项(例如,如果Book保证默认构造函数不能提供的不变量),你可以引入一个默认构造的中间数据传输类,可以填充通过operator>>获取数据,并可转换为Book。草图:

class TransferBook {
public:
  // To read data from stream
  friend std::istream &operator>>(std::istream &in, TransferBook &dest);

  // Conversion to Book. Use the non-default Book constructor here.
  operator Book() const {
    return Book(all the data);
  }

private:
  // all the data
};

...

std::vector<Book> books;
std::ifstream file;

// Note that books contains Books and the iterator reads TransferBooks.
// No Book is default-constructed, only TransferBooks are.
std::copy(std::istream_iterator<TransferBook>(file),
          std::istream_iterator<TransferBook>(),
          std::back_inserter(books));

可以肯定的是,这种方法相当麻烦并且基本上重复了代码,并且给Book默认构造函数可能不那么麻烦。但是,如果Book无法以这种方式更改,则可能是一种解决方法。