C++のtypedefって、、、

C++についてふと思ったことを書いてみる。


まずは普通の変数宣言と関数定義

char val; //変数
int array[SIZE]; //配列
int func(int arg1, double arg2){...} //関数

変数の宣言の形は
型名 変数名;
でも配列の場合はサイズが後ろにくる。
これはint[SIZE]という型があるのではなくて
array[x]という操作で戻り値がint型である、って考えたほうがしっくりくる。
そう考えると変数の場合もvalにアクセスするとcharが返ってくる、という風に
全部関数と同じ様にとらえられる。


で、typedefを使った場合

typedef char NewChar;
typedef int IntArray[SIZE];
typedef int Func(int, double);

NewChar c;
IntArray arr;
Func f = func;

変数宣言や関数定義に書き方は似てるけど、
typedefって型をdefineするってことなんだから
typedef 古い型 新しい型;
って感じで一番右に定義する型名が来たほうが見やすいと思う。
むしろ#defineと同じように
typedef 新しい型 古い型;
でもいい。まぎらわしいか。
typedef 新しい型 = 古い型;
ならはっきりするけど、再代入できそうなイメージがつくからダメだね。
それとIntArray arr;ってIntArray型の変数と宣言してるけど、
さっきの考え方とは矛盾するなぁ。
でもarrでIntArray型の変数にアクセスできてIntArray型には[]オペレータがある
って考えたら破綻はしてないか。
でもこれだと配列型があるってことだから、int[4] array;のような宣言ができないとやっぱり不自然かな。
ん?もう一個あるなぁ。
Func fは関数の参照を保存する変数だけど、IntArray arrは配列の実体を定義していて
変数ではない。(代入できない)配列の場合、ポインタでしか参照できないか。
関数の仮引数の場合のみ、配列がポインタとして解釈されるから、参照として使えるか。
なんか対称性ないなぁ。


と、ここまで書いて間違いに気付いた。
関数は

typedef int (* Func)(int, double);

こうだっけ?
つまり、関数定義じゃなくて関数ポインタに対応してると。
だったら納得だよな。
配列を参照したいならポインタをtypedefすればよいだけのこと。


なんか、どうでもよいことを長々と書いてしまった。。。
独り言なので気にしないでください。


ちなみにC++でも構造体をtypedefしてしまうのは少数派かな?
なんか習慣でつい。