windows.hのmin/maxは困る
string streamを使うために、
#include <sstream> // std::ostringstream
とする。これで文字列の構築を出力ストリームへの書き出しとして扱えて便利。
ところが、なんかエラーする。エラーの箇所は次のようなコードのなか。
c:/Installed/MinGW/lib/gcc/mingw32/4.6.2/include/c++/bits/sstream.tcc
template <class _CharT, class _Traits, class _Alloc> typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type basic_stringbuf<_CharT, _Traits, _Alloc>:: overflow(int_type __c) { const bool __testout = this->_M_mode & ios_base::out; if (__builtin_expect(!__testout, false)) return traits_type::eof(); const bool __testeof = traits_type::eq_int_type(__c, traits_type::eof()); if (__builtin_expect(__testeof, false)) return traits_type::not_eof(__c); const __size_type __capacity = _M_string.capacity(); const __size_type __max_size = _M_string.max_size(); const bool __testput = this->pptr() < this->epptr(); if (__builtin_expect(!__testput && __capacity == __max_size, false)) return traits_type::eof(); // Try to append __c into output sequence in one of two ways. // Order these tests done in is unspecified by the standard. const char_type __conv = traits_type::to_char_type(__c); if (!__testput) { // NB: Start ostringstream buffers at 512 chars. This is an // experimental value (pronounced "arbitrary" in some of the // hipper English-speaking countries), and can be changed to // suit particular needs. // // _GLIBCXX_RESOLVE_LIB_DEFECTS // 169. Bad efficiency of overflow() mandated // 432. stringbuf::overflow() makes only one write position // available const __size_type __opt_len = std::max(__size_type(2 * __capacity), __size_type(512)); const __size_type __len = std::min(__opt_len, __max_size); __string_type __tmp; __tmp.reserve(__len); if (this->pbase()) __tmp.assign(this->pbase(), this->epptr() - this->pbase()); __tmp.push_back(__conv); _M_string.swap(__tmp); _M_sync(const_cast<char_type*>(_M_string.data()), this->gptr() - this->eback(), this->pptr() - this->pbase()); } else *this->pptr() = __conv; this->pbump(1); return __c; }
sstream.tccはテンプレートを書いてあるソースで、<sstream>からincludeされてるのだろう。ここで、min/maxが使われている。
const __size_type __opt_len = std::max(__size_type(2 * __capacity), __size_type(512)); const __size_type __len = std::min(__opt_len, __max_size);
このmin/maxがwindows.hで定義されているマクロで置換されてしまう。std::で修飾されているが、プリプロセッサだからお構いなしに置換する。
一方で、windows.hにmin/maxマクロが定義されているのを前提に書いてあるソースもある。どこにも定義されてないmin/maxが使われているのだが、windows.hを当てにしているわけ。
次のブログエントリーにこの件の記述がある。