Wednesday, 15 May 2013

C++ - is it possible to extract class and argument types from a member function type in a template? -



C++ - is it possible to extract class and argument types from a member function type in a template? -

i wrap fellow member functions conform type 'void (classtype::function)(argtype)' templated class. later, want pass instance of classtype instance of template , have invoke wrapped method:

class foo { public: foo() : f_(0.0) {} void set(double v) { f_ = v * 2.1; } double get() { homecoming f_; } private: double f_; }; template <typename argtype, typename classtype, void (classtype::*method)(argtype)> class wrapper { public: explicit wrapper(classtype *cls) : cls_(cls) {} void do_something(argtype value) { (cls_->*method)(value); } private: classtype *cls_; }; #include <iostream> int main(int argc, char ** argv) { foo foo; wrapper<double, foo, &foo::set> wrapper(&foo); wrapper.do_something(1.0); std::cout << foo.get() << std::endl; // outputs "2.1" homecoming 0; }

notice in instantiation of wrapper<> "foo" specified twice - looks redundant here.

so i'd know whether it's possible avoid template parameter classtype. instance, if possible imply or extract fellow member function pointer parameter, wouldn't need explicitly specified in instantiation of wrapper<>.

in similar manner, useful avoid explicitly specifying argtype also, (perhaps) can determined foo::set?

is possible in c++? perhaps along these (entirely fantastical) lines:

template <void (classtype::*method)(argtype)> class wrapper2 { public: explicit wrapper(method::classtype *cls) : cls_(cls) {} void do_something(method::argtype value) { (cls_->*method)(value); } private: method::classtype *cls_; }; // ... int main() { foo foo; wrapper<&foo::set> wrapper(&foo); // ... }

or, perhaps there's level of template magic can invoked along these lines:

wrapper<magic<&foo::set> > wrapper(&foo);

i'm interested know mechanisms might available, if any.

i'm using c++03 requirement, not c++11, interested know c++11 might offer.

edit: more info - intend utilize mechanism wrap ~300 fellow member functions (all belonging classtype, or set of similar classes), there around 6 or signatures consider:

void (classtype::function)(argtype) - argtype 'floating' void (classtype::function)(argtype) - argtype 'integral' void (classtype::function)(bool) void (classtype::function)(indextype, argtype) - above 3 'index' argument

the fellow member functions 'setter' functions phone call "properties" in big configuration 'collection' class, illustration (rather simple foo above):

class mypropertycollection { public: void set_oink(double value) { oink_ = value; } void set_bar(int value) { bar_ = value; } void set_squee(bool value) { squee_ = value; } private: double oink_; int bar_; bool squee_; }; // elsewhere wrappercollection wrapper_collection; // simple set of wrapper objects, accessed id mypropertycollection property_collection; wrapper_collection.add(property_oink_id, new wrapper<double, mypropertyset, &mypropertyset::set_oink>(&property_collection); wrapper_collection.add(property_bar_id, new wrapper<int, mypropertyset, &mypropertyset::set_bar>(&property_collection); wrapper_collection.add(property_squee_id, new wrapper<bool, mypropertyset, &mypropertyset::set_squee>(&property_collection); // +300 more

in c++11 might utilize lambdas, like:

template <typename x, typename arg> std::function<void(x*, arg)> wrapper(void (x::*mfp)(arg)) { homecoming [=](x *x, arg arg) { (x->*mfp)(arg); }; }

with visualc++ (at to the lowest degree recent vs2013), utilize capture value [=] when capturing fellow member function pointers (or experience crashes).

playground:

#include <iostream> #include <functional> struct { virtual void a(int i) { std::cout << "a: " << << std::endl; } }; struct b { virtual void b(int i) { std::cout << "b: " << << std::endl; } }; template <typename x, typename arg> std::function<void(x*, arg)> wrapper(void (x::*mfp)(arg)) { homecoming [=](x *x, arg arg) { (x->*mfp)(arg); }; } int main() { auto g = wrapper(&b::b); b b; g(&b, 3); auto h = wrapper(&a::a); a; h(&a, 4); homecoming 0; }

c++ templates template-meta-programming member-function-pointers

No comments:

Post a Comment