2009-05-07

C++の新しいtypedef方法、alias declaration

Template Aliasは、テンプレートに対するtypedefだけかと思っていたら、どうも、alias declarationといって、typedefと同等の機能も提供しているようだ。知らなかった。

using type1 = int ;
using type2 = int [10] ;
using type3 = type1 (*) ( type2 ) ;

その意味を説明するまでもないほど、とても分かりやすい。やはり、別名を最初に記述できるのが、分かりやすい理由だろう。この宣言を読めば、何の型かはともかくとして、とにかく、別名の名前は、簡単に分かる。しかる後に、右側を読めば、型が分かる。ちなみに、C++03では、以下のように書かなければならない。

typedef int type1 ;
typedef int type2[10] ;
typedef type1 ( * type3 ) ( type2 ) ;

typedefの文法の問題点は、別名が容易に分からないことだ。しかも、配列や関数になると、別名がどれかを探さなければならない。

まず、最も簡単なtype1の宣言でも、別名を後に記述しなければならないので、読みにくい。
type2は、配列型なのだが、とても読みにくい。
type3は、あの忌まわしき関数ポインタである。関数ポインタのtypedefは、初心者殺しと、私は勝手に呼んでいる。関数ポインタをtypedefする文法は、とても分かりにくい。慣れることはできない。

ところで、変数の宣言に、こんな構文が欲しいと、ふと思った。つまり、変数名が先に来る構文だ。もっとも、変数名が容易に分からないような複雑な型の場合は、typedefを使うだろうから、それほど問題ではないのだが。

関数ポインタの型に名前を付ける - Faith and Brave - C++で遊ぼう

2 comments:

egtra said...

実用性はさておきboost::mpl::identifyでそのようなことが可能です。こちらは型が先になりますが。
void f(int, double);
identity<void (*)(int, double)>::type p1 = g; // void (*p1)(int, double) = g;
identity<void (int, double)>::type* p2 = g; // p1と同じ型
typedef identity<void (*)(int, double)>::type ptr_f_t; // typedefにも使用可能

江添亮 said...

そういえばそうだ。