C++の不思議な仕様をもう一つ発見。やはり C++ は発見に満ちている。
enum E{ EZero = 0 }; const int zero = 0; void test() { char * c; c = EZero; // これはエラー c = false; c = 1<0; c = '\0'; c = 0; // これは正しいに決まっている。 c = zero; // これも正しいに決まっている。 c = 1/3; // 正しいけど。 c = 0UL; c = 0.0; // これはエラー c = static_cast<int>( 0.1 ); }
私にはやや意外な仕様なんだが、「これはエラー」と書いたもの以外はエラーにならない。
意外だったのは、char・bool・unsigned long を右辺にしても int への暗黙の変換でポインタに代入できてしまうところ。C++ のこういうところを整理しただけの言語を ++C とかいう名前で誰か作るといいんじゃないかと思うが、どうだろう。
で。以下のようにするとトラブルになる:
struct x{ x(double){} }; void foo( char * c ){ cout << "char *" << endl; } void foo( x ){ cout << "x" << endl; } void test() { foo( 1/3 ); // foo( char * ) が呼ばれる foo( 4/3 ); // foo( x ) が呼ばれる }
これで仕様通りだと思うが、大変わかりにくい。
ポインタ型を受ける関数と数値型を受ける関数を同名にしたら負けというのは、まあある程度知られているとは思うが、実際に上記のコードが上記の通りに動くことをわかっている人は少ないと思う。