はじめてのRTTI

Run Time Type Infomationの略ですね。具体的にはtypeidとdynamic_castの二つですね。ひょっとしたらまだあるかもしれないけど私はこの二つしか知らない(^^; この二つの文法は詳しく書いてあるサイトはいくらでもあるので割愛いたします。

私も一応それなりにC++の経験が長い(?)ですがRTTIを使うのは今回が初めてだったり。なんで今まで使ったことがなかったのか?理由は簡単。必要がなかったから。ただそれだけ。

個人的に思うに、RTTIってC++っぽくないんですよね。実行時に型の情報を利用するという機会自体、C++ではあまりないんですよね。テンプレート使えば必要になることはまず考えられない。ありえたとしたら設計を疑うべきだろうと心に決めている(ぇ ちなみにテンプレートはコンパイル時に型の情報が決定するので、RTTIではない。無理に名前をつけるとしたら「Compile Time Type Infomation」だろうか?

じゃあなんでRTTIがC++にあるのか?まあここから先は完全に個人の見解(よーするに出鱈目(ぇ)なのだが、RTTIってオブジェクト指向っぽいんですよね。例えばJAVAだが、ポインタのキャストがデフォルトでdynamic_castになっている。C#も確かそうだったと思う。OOP言語ならRTTIがわりと普通なんですよね。特にJAVAC#も嘗てはテンプレート的な文法が無かった頃はジュネリックを実現しようと思ったらobject型にポイポイ入れるのが普通だったものだからダウンキャストは必須だった。そうなるとRTTIがないと開発効率が劇的に悪かったと思われる。そういった背景からかC++も一応OOP言語を名乗るためにはRTTIが必要だったんじゃないかな?などと邪推している。

しかし、C++はテンプレートがあった。なのでRTTIが必要なかった。ていうか、なによりも速度を重視するC++にとってしてみれば型情報を実行時まで持って行きたくなかったんじゃないかな?実際、VCではコンパイルオプションをつけないと使えないし。
「テンプレートがあれば全部出来るのか?」と言われればそれは確かに無理なこともある。テンプレートは静的なのだから動的な処理は無理。抽象化されたオブジェクトにいろいろな具現化したオブジェクトを入れて一括して扱う場合に一部の具現化したオブジェクトにだけ特別処理をする場合とかはテンプレートでは不可能。RTTIで実行時にそれぞれの具現化したオブジェクトの識別が必要になる。しかしこの例はそもそも設計に失敗していないか?具現化したオブジェクトの識別が必要という時点で抽象化に失敗しているってことでしょ?適切に抽象化が出来ていればオブジェクトの識別など必要ないはず。
他にもなにかテンプレートで出来ない例があるかもしれないのでこれ以上言うことは出来ないが、それでも少なくとも私には今まで必要と感じたことが全く無かった。や、無くも無いが設計見直しで普通に回避できた。



んで最初に戻って、なんで今回必要になったか?お得意のテンプレートを使えば何とかなるんじゃないのか?いやまあ、理論上は出来るハズなんですが文法上は今のC++では無理。具体的には型の名前そのままをファイルに書き出したかった。

template< class TYPE_NAME >
void write( TYPE_NAME* aValues, int iSize )
{
	std::ofstream fout( "result.h" );
	fout << "const ";
	fout << typeid( TYPE_NAME ).name();
	fout << " g_aValue[" << iSize << "] = { ";
	for( int i = 0; i < iSize; ++i ){
		fout << aValues[i] << ", ";
	}
	fout << "};" << std::endl;
}

まあこんな感じ。プログラムでプログラムを書く・・・と言えばちょっとカッコいいですが(ぇ まあそんなところです。明らかに使い方間違っているよな(’’
TYPE_NAMEはテンプレート引数なのでコンパイル時には決定しているので名前も当然わかるわけなのでRTTIである必要はないのですが、typeid以外で型の名前を得る方法がC++にはないのでこのようになっております。

まあこのあたりも今後、C++は変わっていくのかなぁ〜等と考えたりしてますが果たしてどうなることやら・・・。