C++版いろはうた

しのはらのC++実験室トップページ

C++の予約語すべてを一つずつ使ってプログラムする

 現在のC++には実に60を超える数の予約語があります。
 ある日、次のような命題を思いつき挑戦してみました。
以下の条件を満たすC++プログラムは作れるか。
・C++の予約語すべてを一つずつ含む
・プリプロセッサ指令を含まない
 以下に僕の知りうる限りの予約語を列挙します。
auto asm bool break case catch char class const const_cast
continue default delete do double dynamic_cast else enum
explicit extern false float for friend goto if inline int
long mutable namespace new operator private protected
public register reinterpret_cast return short signed
sizeof static static_cast struct switch template this
throw true try typedef typeid typename union unsigned
using virtual void volatile wchar_t while

結論

結論から言うと、そのようなプログラムは作れると思います。
一応作れました。
ソースコードはこちら

考察

 プログラムを作ると言っても上記の制約条件に従えば長さに限界があります。 また考えてみればいろいろな制約条件が存在することが分かります。
 たとえば以下のようなことが分かります。

型名はいくつ存在しうるか
 型名はまず型を表す予約語によって bool, char, short, unsigned, signed, int, long, float, double, wchar_t の10個が表現できます。 もちろんそれらへのポインタや配列、 constvolatile 修飾子つきのものもあり得ますが、 同じ型名を2度以上使えないので同じことです。 また、unsigned charなどのような型も使用できますが、 そうするとunsignedchar が使えなくなるので、使用できる型の数が減ってしまいます。
 予約語の他には struct, class, enum, union, typedef を使用することでそれぞれ一つずつの型識別子を増やすことが出来ます。 ただしこれらによって生成した型識別子は予約語ではないので、 もはやプログラム中に何度でも使用できます。
 以上からとりあえず、 15個までしか型名は存在できないことが分かります。

関数はいくつ存在しうるか
 特に大きな制限として関数の種類があげられます。
 main関数は周知の通りint型を返します。 また、値を返す関数は当然returnを使用しなければなりません。 このことから、 main関数以外に値を返す関数は定義できない、 ということが分かります。
 というわけで値を返さない関数なら定義できることになります。 しかし値を返さない関数には以下のものしかありません。
  ・voidで宣言された関数
  ・コンストラクタ
  ・デストラクタ
 特にvoidで宣言された関数というのは、 予約語voidを使用せざるを得ないため、 たった一つしか作れません。 コンストラクタは、 クラス定義中であれば一つも予約語を使用せずに書けるので、 いくつでも定義できます。 デストラクタは当然クラス一つにつき一つしか定義できません。
 以上から、int main() とたった一つのvoid関数以外には、 コンストラクタとデストラクタしか定義できない、 と分かります。

その他、考えたこと
 ・elseにはifが必要。
 ・catchにはtryが必要。
 ・case, defaultにはswitchが必要。
 ・doにはwhileが必要。
 

感想

 一応プログラムとして書くからには、 それぞれの予約語をそれなりの意味のある文脈で使用したいと思って、 いろいろ工夫しました。でも結局プログラム全体としては、 何の意味もないものになってしまいました。 もし制約条件として「全体として意味のあるプログラム」 を加えたとしたらどんなプログラムが可能なのか、 興味はありますが相当の工夫が必要になると思われます。 誰かやらないでしょうか。
 最初から出来るだろうとは思っていたのですが、 試行錯誤の末、突然出来たときには「あれ?出来てるらしいぞ」 という感じで、少し驚きました。