Effective STL条項29

2152 ワード

条項29:1文字入力が必要な場合はistreambufを使用することを考慮します.iterator
テキストファイルを文字列オブジェクトにコピーするとします.理にかなった方法で完成できるようです.
ifstream inputFile("interestingData.txt");
string fileData((istream_iterator(inputFile)),   //  inputFile  
   istream_iterator());   // fileData;     
        //          
        //          
        //     6

この方法では、ファイルのスペースを文字列にコピーできないことがすぐにわかります.それはistream_iterators operator<を使用
スペースを残したい場合は、デフォルトを上書きします.入力ストリームのskipwsフラグをクリアすればいいです.
ifstream inputFile("interestingData.txt");
inputFile.unset(ios::skipws);    //   inputFile 
       //       
string fileData((istream_iterator(inputFile)), istream_iterator());

InputFileのすべての文字がfileDataにコピーされました.
ああ、それらのコピー速度はあなたが想像していたほど速くないことに気づきます.istream_iteratorsが頼るoperator<
より効率的な方法はSTLの最高の秘密兵器の一つであるistreambuf_iterators.あなたはistreamのようにiterator同様istreambuf_を使用iterator,ただしistream_iteratorオブジェクトはoperator<オブジェクトを使用してストリームのバッファに入り、次の文字を直接読み込みます.(より明確には、1つのistreambuf_iteratorオブジェクトが1つのistream sから読み込まれると、s.rdbuf()->sgetc()を呼び出してsの次の文字を読みます.)私たちのファイル読み取りコードをistreambuf_を使用するように変更します.iteratorはかなり簡単で、ほとんどのVisual Basicプログラマーは2回の試みで正しいことをすることができます.
ifstream inputFile("interestingData.txt");
string fileData((istreambuf_iterator(inputFile)),
   istreambuf_iterator());

ここでは「unset」skipwsフラグは必要ありません.istreambuf_iteratorは文字を無視しません.ストリームバッファの次の文字のみを取得します.
istream_に対してiterator、それらはもっと速く捕まえられます.私が行った簡単なテストでは40%速くなります.もしあなたの結果が違っても驚く必要はありません.時間が経つにつれて、速度の優位性が増加してもおかしくない.istreambuf_iteratorはSTLのあまりアクセスしないコーナーに存在するため、実装にはまだ最適化に多くの時間がかかりません.例えば、私が使った実装ではistreabuf_iteratorは私の主なテストでistreamよりしか優れていません.iteratorは約5%速くなりました.そのような実装には明らかにistreambufを最適化する余地がたくさんあります.iterator実装.ストリーム内の文字を1つずつ読み取る必要がある場合は、入力の威力をフォーマットする必要はありません.ストリームを読み取るのにどれだけの時間がかかるかに関心を持っています.明らかなパフォーマンスの向上に比べて、反復器ごとに3文字を多く入力する代価は微弱です.フォーマットされていない文字入力の場合は、istreabuf_の使用を常に考慮する必要があります.iterator.
それを知ったらostreambufも考えなければなりませんiteratorは、対応するフォーマットなしで1文字ずつ出力する作に使用されます.彼らはostreamを持っていませんiteratorのオーバーヘッド(および弾力性)なので、通常はよりよくできます.