0

Based on post How to call a function by its name (std::string) in C++?, tried to make a version using CLASS, but my approach does not work.

class A { public: int add(int i, int j) { return i+j; } int sub(int i, int j) { return i-j; } }; typedef int (*FnPtr)(int, int); int main(int argc, char* argv[]) { // initialization: std::map<std::string, FnPtr> myMap; A a; myMap["add"] = a.add; myMap["sub"] = a.sub; 

Returns this erro:

main.cpp:31:22: error: cannot convert ‘A::add’ from type ‘int (A::)(int, int)’ to type ‘std::map<std::basic_string<char>, int (*)(int, int)>::mapped_type {aka int (*)(int, int)}’ main.cpp:32:22: error: cannot convert ‘A::sub’ from type ‘int (A::)(int, int)’ to type ‘std::map<std::basic_string<char>, int (*)(int, int)>::mapped_type {aka int (*)(int, int)}’ 

Does anyone know what is the error?

6
  • 1
    Member functions are not functions. You cannot call a member function (like "myMap["add"](1, 2)"), because that makes no sense. Instead, you need to combine the class member A::add and the instance object a in some way. Commented Oct 20, 2013 at 17:06
  • A pointer-to-member is not the same as a pointer-to-non-member. But you would have been able to find this yourself if you had googled the compiler error. Change typedef int (*FnPtr)(int, int); to typedef int (A::*FnPtr)(int, int); and call it like a.*(myMap["add"])(42, 1337);. Horrible, isn't it? Commented Oct 20, 2013 at 17:06
  • You have a more fundamental problem here: member functions are not the same as non-member functions. Commented Oct 20, 2013 at 17:07
  • 2
    Use perhaps std::function + std::bind Commented Oct 20, 2013 at 17:07
  • Are all your functions members of class A? Commented Oct 20, 2013 at 17:15

2 Answers 2

2

At least as you've shown things, your class A provides nothing but problems. If you turn it into a namespace, things will be a lot easier.

namespace A { int add(int i, int j) { return i+j; } int sub(int i, int j) { return i-j; } }; typedef int (*FnPtr)(int, int); int main(int argc, char* argv[]) { std::map<std::string, FnPtr> myMap; myMap["add"] = A::add; myMap["sub"] = A::sub; // ... 

This way, add and sub aren't member functions, so you don't get the type mismatch. At least as shown, the instance of A provided no functionality beyond calling add and sub, so a namespace accomplishes just as much good while eliminating the problems.

Sign up to request clarification or add additional context in comments.

1 Comment

Nice and straight-forward. Static class members would provide a similar alternative, with the benefit of being templatable.
0

You could also solve the problem, as mentioned by Kal in the comments, using std::function and std::bind(this is C++11 so):

#include <iostream> #include <string> #include <map> #include <functional> class A { public: int add(int i, int j) { return i+j; } int sub(int i, int j) { return i-j; } }; int main(int argc, char* argv[]) { std::map<std::string, std::function<int(int,int)>> myMap; A a; myMap["add"] = std::bind(&A::add,&a,std::placeholders::_1,std::placeholders::_2); myMap["sub"] = std::bind(&A::sub,&a,std::placeholders::_1,std::placeholders::_2); std::cout<<myMap["sub"](7,2)<<std::endl; } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.