私はこのようなコードを持っています:
template<> const string &Wrapper<Foo>::s_Name = "Foo";
template<> const Binding Wrapper<Foo>::s_Bindings[] = {
Binding("m1", &caller<&Foo::f1>),
Binding("m2", &caller<&Foo::f2>),
Binding("m3", &caller<&Foo::f1>),
Binding("outer", &caller<&outer>),
};
template<> const int Wrapper<Foo>::s_BindingsLength =
(sizeof(ArraySizeHelper(s_Bindings)));
ArraySizeHelperは、コンパイル時に配列サイズを計算します。非メンバー関数とメンバー関数をバインドできます。これらのバインディングを作成する時間を節約するために、いくつかのマクロを作成しました。
#define BIND_START(Class) \
namespace _Bind##Class##Namespace { \
typedef Class _BindClass; \
template<> const string &Wrapper<_BindClass>::s_Name = #Class; \
template<> const Binding Wrapper<_BindClass>::s_Bindings[] = {
#define BIND(FunctionName, Function) \
Binding(FunctionName, &caller<Function>),
#define BIND_END \
};\
template<> const int Wrapper<_BindClass>::s_BindingsLength = \
(sizeof(ArraySizeHelper(s_Bindings))); \
}
上記のコードは次のように記述できます。
BIND_START(Foo)
BIND("m1", &Foo::f1)
BIND("m2", &Foo::f2)
BIND("m3", &Foo::f1)
BIND("outer", &outer)
BIND_END
入力と読み取りがはるかに簡単です。なぜ名前空間に入れる必要があるのですか?クラス名を一度だけ(メンバー関数ポインターを除いて)記述し、それを複数のクラスで使用する必要があるような方法でこれらのマクロを記述する別の方法を見つけることができないためです。そして今、私は疑問に思っています、それをしても大丈夫ですか?そうでない場合、私が望む機能を実装する他の方法はありますか?
GCC 4.7.2のバグのようです(他のバージョンについてはわかりません)
このコードは9.4.2/2に違反しています。「静的データメンバーの定義は、メンバーのクラス定義を囲む名前空間スコープに表示されます。」
バグレポートは次のとおりです。GCCBugzilla–バグ56119