続seek

今日も会社にお泊りの可能性大なので、朝更新。
似たインタフェースとして、basic_streambuf::seekoff()を調べてみました。

pos_type seekoff(
    off_type off, ios_base::seekdir way,
    ios_base::openmode which = ios_base::in | ios_base::out);

実際にはbasic_streambufの規定はほとんどなく、basic_stringbufとbasic_filebufの仕様になります。
basic_stringbufはdual_seekable、つまり一つの文字シーケンスに入力用と出力用の2つのヘッドを持ちます。whichは2つのヘッドのどちらを(あるいは両方を)移動させるかを指定します。2つのヘッドを同時に移動させる場合はwayがbegかendである必要があります。
basic_filebufはseekable、つまり入出力を同一のヘッドで行います。whichは無視されます。

昨日の問題のコードはbasic_filebuf::seekoff()の動きに似ていますが、そもそもヘッドが1つしかない場合にも引数whichがあるのが変な気がします。basic_streambufの場合は仮想関数なので引数の数を減らすことはできませんが、Boost.Iostreamsの場合はそうではないのでseek関数を2つ用意すればよかったのではないかと思います。

// two_head用
template<typename T>
std::streampos 
seek( T&, stream_offset  off, std::ios_base::seekdir way,
      std::ios_base::openmode which );

// one_head用
template<typename T>
std::streampos 
seek( T&, stream_offset  off, std::ios_base::seekdir way );

バイスメンバ関数seekもこの方式(whichのデフォルト値はなし)に合わせておけば意図しないシークが避けられるでしょう。