Reputation:
Static array initialization... with const pointers... to overloaded, templatized member functions. Is there a way it can be done (C++03 standard code)? I mean, if I have the template class
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)?
Notes:
1. As a static array MUST be initialized at file scope, template parameters and pmfi must be full qualified (the only way I know to access template parameters outside a class scope is to typedef them...).
2. So far so good. No problems with the compiler (Comeau 4.3.10.1). Problems start popping up when I try to fullfill the initializer list { ... }.
2.1. The compiler complains the template argument list is missing, no matter what I do.
2.2. I have no idea how to select the correct overloaded U::f function.
BTW, this is a kind of "jump table" generator from a boost.preprocessor list. The code I am trying to implement is of course much more complex then this one, but this is his essence.
Thanks for any help
Upvotes: 1
Views: 609
Reputation: 791371
To use BOOST_PP_ENUM
in the way that you've shown, you would need a macro that takes a 'number' and yields an expression that is the address of an appropriate member of the appropriate class. I don't see a good way to do this without an explicit list unless the desired functions all have manufactured names (e.g. memfun1
, memfun2
, etc.). Except in the case, it's going to be easier to list the function address expressions explicitly that to used BOOST_PP_ENUM.
You are using identifiers in this array that are the same as the template parameters in Some_class
.
R (U::* const pmfi[])(T&) = { /* ... */ }
Is this really supposed to be the templated member of Some_class?
template< class T, class U, class R >
R (U::* const Some_class<T, U, R>::pmfi[])(T&) = { /* ... */ }
If so, is the same instantiation going to work with all combinations of types that you are going to us the template Some_class
with? If so, you have a very constrained set of classes, perhaps you can do away with the template. If not, you are going to have to specialize Some_class
for every combination of template parameters in which case the template is not gaining you very much.
Edit, post edit: If I've understood you correctly then you can't do what you've suggested because the array of pointers must be of exactly the right signature.
Reducing it to a simple function pointer example, you can't do this:
void f(Derived&);
void (*p)(Base&) = &f;
otherwise, it would subvert type safety:
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);
In your array of function pointers, the initializers must all be to functions of the right signature.
Upvotes: 1