« 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:
https://labs.cybozu.co.jp/cgi-bin/mt-admin/mt-tbp.cgi/1943