忘れやすいC++の仕様(1/3)

私は10年ほど前にC++の仕様を隅から隅まで覚えたことがあるが、それから10年、全く触っていない。Cは時々接するのでANSI Cの仕様はまだ結構覚えているが、C++の仕様は全般的にうろ覚えだ。
そんな状態で、久々にC++の仕様を眺めていると、すっかり忘れていることがいくつもあったので、ここに記す。

(1) 構造体内の構造体定義の参照

struct Outer{
	struct Inner{
	int i;
	} j;
}
というコードのInnerを参照する場合、Cだと
struct Inner i;
とできるが、C++だと
struct Outer::Inner i;
としないといけない。

(2)int値のenum型への変換
Cでは

enum Color {RED=1, GREEN, BLUE};
enum Color c;
c = 1;
ができるが、C++ではできない。
c = Color(1);
c = (Color)1;
のようにする必要がある。
蛇足だが、Cで"c = Color(1);"とすると、コンパイルエラーとはならず、Color()という関数が無いというリンクエラーになる。

(3)template文はクラス定義以外にも使える

template<class T> T square(T x)
{
	T y;
	y = x * x;
	return y;
}
のような関数定義もできる。
ひょっとしてtemplateをクラス定義にしか使えないと思い込んでいる人は少数だろうか。

(4)通常型引数と参照型引数の多重定義
C++では引数の型を変えて同じ名前の関数を多重定義できるが、

void foo(int i) {}
void foo(int &i) {}
の2つを同時に定義することはできない。
よく考えると、これらの関数を呼び分けられないので当然とも思える。
同様に
void foo(int i) {}
void foo(const int &i) {}
の組み合わせも不可だが、
void foo(int &i) {}
void foo(const int &i) {}
の2つは同時に定義できる。
なお、g++では重複定義自体はエラーにならず、呼び出し文にてコンパイルエラーとなった。