ifstreamの挙動が気に入らない

バイナリファイルをifstreamで操作しようとしたら不満が出たので。

  • readの返り値は自身のオブジェクト(読み込んだbyte数じゃない)
  • ios::binaryの時のoperator >>(...)の挙動がヤダ

なので、オレオレBinaryFileReaderを作りました。自己満足です。
ifstreamの良さが分かる日はくるのだろか。

#include <cstdio>
class BinaryFileReader{

	BinaryFileReader();
	BinaryFileReader(const BinaryFileReader &);
	BinaryFileReader & operator =(const BinaryFileReader &);
	
	FILE *fp;
	
	template<typename T> BinaryFileReader & operator>>(T * o); // ポインタを渡すのを許さない(追記)
public:
	enum SEEK_TYPE{
		Beg = SEEK_SET,
		Cur = SEEK_CUR,
		End = SEEK_END
	};
	
	BinaryFileReader(const char *filename) : fp(fopen(filename, "rb")){ }
	
	~BinaryFileReader(){
		fclose(fp);
	};
	
	inline size_t read(void *p, size_t datasize, size_t datanum){
		return fread(p, datasize, datanum, fp);
	}
	
	inline size_t read(void *p, size_t readlength){
		return read(p, 1, readlength);
	}
	
	template<typename T> BinaryFileReader & operator >>(T &o){ read(&o, sizeof(T)); return *this; }
	
	inline bool eof() const { return feof(fp); }
	inline int seek(int length, SEEK_TYPE origin)  { return fseek(fp, length, origin); }
	inline int seek(int length)  { return seek(length, Cur); }
};


こんな使い方をします。

char magic[4];
int i;
short s;
BinaryFileReader bfr("hoge.bin");

bfr.read(magic, 4); // 先頭から4byte取得
bfr >> i; // 4byte目から4byte(==sizeof(int))取得
bfr >> s; // 8byte目から2byte(==sizeof(short))取得
bfr.seek(0, BinaryFileReader::Beg); // fpを先頭に移動
bfr >> i; // 先頭から4byte取得


Template便利だなー。
operator >>()へポインタを渡せてしまうので、その時は32bit環境なら4byte読み込むでしょう。
なので、char a[2]; bfr >> a;とかしちゃうと、バッファオーバーフローになります。
これを制限する方法が思いつきませんでした。知識不足でダメダメですね。

追記

手持ちの本を調べたら、privateにtemplateでポインタ型を渡されたときの定義だけを書いて、実装はしない事で回避できます。
よくわからないので穴があるかもしれませんが、バッファオーバーフローが起こりうるコードを晒しておく現状よりマシです。

test.cpp: In constructor 'HLDemoParser::HLDemoParser(const char*)':
test.cpp:10:42: error: 'BinaryFileReader& BinaryFileReader::operator>>(T*) [with T = char, BinaryFileReader = BinaryFileReader]' is private
test.cpp:55:11: error: within this context

このエラー文だと、55行目でそのテンプレートを使おうとしているのでエラーになります。
該当箇所もわかって良いですね:)
また、ポインタのポインタでも同様に該当します。