Universal Function Pointer

There is some class that has methods such as:

int getSomething1(); std::string getSomething2(); someClass getSomething3(); 

There is a structure that describes the fields of this class:

 {"name of field", pointer to getter, std::type_info} 

Then I would use it as follows:

 if(type == int){ field_int = (int)getter(); } else if(type == std::string){ field_string = (std::string)getter(); } etc. 

How to convert getters, for example

  int getSomething1(); std::string getSomething2(); etc. 

to some universal function pointer, and then to get the correct field value?

+4
source share
5 answers

This answer on my other question relates to your problem pretty well. With some minor changes, you will get the following:

 template<class C, class T> T get_attribute(const C& instance, T (C::*func)() const) { return (instance.*func)(); } 

Assuming the following:

 struct Foo { int getSomething1() const; std::string getSomething2() const; someClass getSomething3() const; }; 

You can use it as follows:

 Foo foo; int value = get_attribute<Foo, int>(foo, &Foo::getSomething1); std::string value = get_attribute<Foo, std::string>(foo, &Foo::getSomething2); someClass value = get_attribute<Foo, someClass>(foo, &Foo::getSomething3); 

You can, of course, convert get_attribute to a functor to bind some or all of the arguments.

+2
source

What you are trying to achieve can be better achieved with existing containers such as boost fusion sequence. I would advise you to try first.

+1
source

There is no formal universal function pointer equivalent to void* for data. The usual solution is to use void (*)() ; You are guaranteed that you can convert any (non-member) pointer to this function (or any other type of function pointer) and vice versa without loss of information.

If there is a certain similarity in function signatures (for example, all are getters, without arguments) and how they are used, it can be possible to deal with this abstract base class and a set of derived classes (possibly template); putting pointers to examples of these classes on a map would definitely be more elegant than a huge switch.

+1
source

Templates for salvation!

 // Create mapping of type to specific function template <typename T> T getSomething(); // No default implementation template <> int getSomething<int>() { return getSomething1(); } template <> std::string getSomething<std::string>() { return getSomething2(); } template <> someClass getSomething<someClass>() { return getSomething3(); } // Convenience wrapper template <typename T> void getSomething(T& t) { t = getSomething<T>(); } // Use int i = getSomething<int>(); std::string s; getSomething(s); 
0
source

As far as I understand, your difficulty lies in storing function pointers, as they have different types. You can solve this problem using Boost.Any and Boost.Function .

 #include <boost/any.hpp> #include <boost/function.hpp> int getInt() { return 0; } std::string getString() { return "hello"; } int main() { boost::function<boost::any ()> intFunc(getInt); boost::function<boost::any ()> strFunc(getString); int i = boost::any_cast<int>(intFunc()); std::string str = boost::any_cast<std::string>(strFunc()); } 
0
source

All Articles