2016-11-26 8 views
3

私のクラスタイプのSTL Vectorをバイナリファイルに書き込んでいますが、istream_iteratorの何が問題なのか分かりません。
プロジェクトルールでは、ブーストのようなサードパーティライブラリと同じテキストファイル を使用できません。istream_iteratorを使ってカスタムタイプのベクトルを構築する

これはBook.hです:

class Book{ 
    public: 
    Book(const std::vector<Book>& in_one_volumes,const std::string& title, 
    const std::string& author,const int pagecount,const int price,const std::string& date); 
    private: 
    std::vector<Book> inOneVolumes; 
    std::string title; 
    std::string author; 
    int pagecount; 
    int price; 
    std::string date; 
}; 

これは、書き込み方法である:

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;  
} 

Compiller氏は述べています - ブック:適切なデフォルトコンストラクタは使用できません。

答えて

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をこのように変更できない場合は、これが回避策です。

+0

大変ありがとうございました。 – Zulcom

関連する問題