静态数组初始化...使用const指针...来重载,模板化的成员函数。有没有办法可以做(C ++ 03标准代码)?我的意思是,如果我有模板类
template <class T1, class U1, typename R1> class Some_class { public: typedef T1 T; typedef U1 U; typedef R1 R; R operator()(T& v) { /* dereference pointer to a derived class (U), overloaded member function (U::f) */ }; private: static R (U::* const pmfi[/* # of overloaded functions in U */])(T&); }; Used as template <class BASE, typename RET> class Other_class : public Some_class<BASE, Other_class<BASE, RET>, RET> { RET f(/* type derived from BASE */) {} RET f(/* other type derived from BASE */) {} RET f(/* another type derived from BASE */) {} ... }; Question: how can I initialize de array pmfi (no typedefs, please)?
注意:
1.由于静态数组必须在文件范围初始化,模板参数和pmfi必须是完全限定的(我知道在类范围外访问模板参数的唯一方法是键入它们...)。
到目前为止一切顺利。编译器没有问题(Comeau 4.3.10.1)。当我尝试填充初始化列表{...}时,问题开始弹出
2.1。编译器抱怨模板参数列表丢失,无论我做什么
2.2。我不知道如何选择正确的重载U :: f函数。
BTW,这是一种来自boost.preprocessor列表的“跳转表”生成器。我试图实现的代码当然比这个更复杂,但这是他的本质。
感谢您的帮助
答案 0 :(得分:1)
要以您显示的方式使用BOOST_PP_ENUM
,您需要一个带有“数字”的宏,并生成一个表达式,该表达式是相应类的适当成员的地址。除非所需的功能都具有制造名称(例如memfun1
,memfun2
等),否则我没有看到没有明确列表的好方法。除非在这种情况下,使用BOOST_PP_ENUM显式列出函数地址表达式会更容易。
您在此数组中使用的标识符与Some_class
中的模板参数相同。
R (U::* const pmfi[])(T&) = { /* ... */ }
这真的应该是Some_class的模板化成员吗?
template< class T, class U, class R >
R (U::* const Some_class<T, U, R>::pmfi[])(T&) = { /* ... */ }
如果是这样,同一个实例化是否适用于您要使用模板Some_class
的所有类型组合?如果是这样,你有一组非常有限的类,也许你可以取消模板。如果没有,您将不得不为模板参数的每个组合专门化Some_class
,在这种情况下,模板不会让您受益匪浅。
编辑,发布编辑:如果我理解正确,那么你就不能按照你的建议去做,因为指针数组必须是正确的签名。
将它简化为一个简单的函数指针示例,你不能这样做:
void f(Derived&);
void (*p)(Base&) = &f;
否则,它会破坏类型安全:
OtherDerived od; // derived from Base, but no from Derived
// I've managed to pass something that isn't a Derived reference to f
// without an explicit (and dangerous) cast
(*p)(od);
在函数指针数组中,初始值设定项必须都是正确签名的函数。