Как вызвать функцию по имени. Подход с использованием STL :: map и Class

На основании поста Как вызвать функцию по имени (std :: string) в C ++?, пытался сделать версию с использованием CLASS, но мой подход не работает.

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;

Возвращает эту ошибку:

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)}’

Кто-нибудь знает в чем ошибка?

0

Решение

По крайней мере, как вы показали вещи, ваш class A не предоставляет ничего, кроме проблем. Если вы превратите его в пространство имен, все будет намного проще.

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;
// ...

Сюда, add а также sub не являются функциями-членами, поэтому вы не получите несоответствие типов. По крайней мере, как показано, экземпляр A не предоставляет никаких функций, кроме вызова add а также subТаким образом, пространство имен достигает такого же успеха, устраняя проблемы.

2

Другие решения

Вы также можете решить проблему, как упомянул Kal в комментариях, используя std :: function и std :: bind (это C ++ 11 так):

#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;
}
0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector