この話は C++ の知識が必要です.前回のクイズの補足です.
友人から環境に依存するのか,それとも standard でこうなっているのかという質問がありました.前回の話では,
罠 4. 暗黙の変換で,この関数への pointer は boolean になる.
が実は standard かどうか怪しいところでした.そこで,gcc4, icc9, VisualStudio2008 で試してみました.少なくともこの3つではバグでなければ環境に依存します.
Visual Studio 2008
a.obj : error LNK2019: unresolved external symbol "class std::basic_string<char, struct std::char_traits<char>,class std::allocator<char> > __cdecl middle(void)" (?middle@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ) refer
enced in function _main
a.exe : fatal error LNK1120: 1 unresolved externals
---
icc9
a.cc(6): remark #1419: external declaration in primary source file
std::string middle();
---
gcc4
a.cc: In function `int main()':
a.cc:6: warning: the address of `std::string middle()', will always evaluate as `true'
VisualStudio2008 では,リンカでエラーになります.icc9 と gcc4 は -Wall で warning がでますが,コンパイルでき,両者とも 1 を出力します.
私としては,VisualStudio2008 の振舞いが,一番わかりやすいです.というのは,関数の pointer は overload のために,引数によっても変化する可能性があるので,stream の通常の実装のように,型を specialize することができないのでは,と思います.void* を使うと,せっかくの template の意味があまりなくなってしまいます.このような状況下で,暗黙の変換を使って,コンパイル可能にするか,それともエラーにするかは,実装に依存するのではないかと思います.ここでの specialise との関係は,riddle を教えてくれた Peter から聞きました.
とにかく,こんなことがあること自体,C++は 難しいと思います.