« MySQL の ORDER BY を高速化 | メイン | C++ で自動型変換 »
2008年06月25日
なんとなくリフレクション in C++
C++ はとてもいい言語なのですが、リフレクションがありません。昨夜、1年ぶりくらいに C++ でリフレクションしたい熱に感染したのですが、ちょっとググった範囲では良いものが見つからなかったので、作ってみました (単に作りたかっただけという説も)。こんな感じで使います。
#include "reflection.hpp" struct Foo { int i; std::string s; }; // リフレクション情報を定義 namespace reflection { template <> struct def<Foo> : public def_base<Foo> { def() { REFLECTION(i); REFLECTION(s); } }; }; // リフレクションを通してデータを読み込み // 変数が見つからない場合は reflection::name_not_found_error が、 // キャストできない場合は std::bad_cast 例外が送出されます int t = reflection::get<int>(f, "i"); cout << "i=" << t << endl; // リフレクションを通してデータを書き込み reflection::set(f, "s", string("hello world")); // リフレクション情報を iterate して表示 for (reflection::def<Foo>::const_iterator i = reflection::def<Foo>::map.begin(); i != reflection::def<Foo>::map.end(); ++i) cout << i->first << " = " << i->second->get<std::string>(f) <<endl;
このリフレクションライブラリの特徴は、以下のようなものになります。
- type-safe
- 代入、参照時に自動的に型変換を行います (型変換ができない場合は std::bad_cast 例外を送出します)
間違った型を代入しようとするとエラーを返します - 構造体の型が不変
- リフレクションを導入しても構造体が肥大化したり、型のバイナリ互換性が損なわれることはありません
- 実行時のオーバーヘッドがゼロ
- リフレクションに必要な情報は main() 関数の実行前の段階ですべて初期化されます
ライブラリと言っても 50 行程度のコードです。CodeRepos (/lang/cplusplus/reflection) に置いてあるので、よろしければご覧ください。
11:39追記: GCC 拡張である typeof を追放しました。
12:13追記: rev. 14582 だと、GCC 4.0, 4.3, VC8, 9 で動作するようです。
6月30日追記: C++ で自動型変換を行うコードを導入し、API を変更しました。
投稿者 kazuho : 2008年06月25日 08:34
トラックバック
このエントリーのトラックバックURL:
http://labs.cybozu.co.jp/cgi-bin/mt-admin/mt-tbp.cgi/1943