我有一些这样的代码:
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:“静态数据成员的定义应出现在包含该成员的类定义的命名空间范围内。”
这是错误报告:GCC Bugzilla – Bug 56119