1

Problem: I have to call functions with its callee names in class. I tried function-pointer with map by return the pointer of functions in class, but it seemed that compiler doesn't allow me to do that with the error

'&': illegal operation on bound member function expression

I want to create a class with function bind with tis callee name ,so I run a register function in its constructor function, then I want to run the funcion inside the class with its callee name. I simplify the code with below,

#include <string>
#include <unordered_map>

class MyClass
{
    typedef bool(*fun)(int num);
public:
    MyClass() { MyClass_functionReg(); } // not sure if I can do this
    ~MyClass() {}

    bool exec(std::string command)
    {
        fun function = find(command);
        function(num);
        return true;
    }

private:
    std::unordered_map<std::string, fun> v_map;
    int num;
private:
    bool MyClass_functionReg()
    {
        v_map.emplace("A", &a); // error here
        v_map.emplace("B", &b);
        v_map.emplace("C", &c);
        v_map.emplace("ERROR", &c);
        return true;
    }

    fun find(std::string command)
    {
        if (v_map.find(command) != v_map.end())
        {
            return v_map[command];
        }
        else
        {
            return v_map["ERROR"];
        }
    }

    bool a(int num)
    {
        return true;
    }
    bool b(int num)
    {
        return true;
    }
    bool c(int num)
    {
        return true;
    }
    bool error(int num)
    {
        return true;
    }
};

int main(int argc, char** argv)
{
    MyClass t;
    t.exec("A");
    t.exec("B");

    return true;
}

Is it just a syntax error? How can i fix this? Is there anything wrong with the way I implement this functionality?

wohlstad
  • 12,661
  • 10
  • 26
  • 39

1 Answers1

2

There are several issues in your code:

  1. You need to use pointer to method for your fun type:
typedef bool(MyClass::*fun)(int num);
  1. When adding the methods to the map, you need to add the class name qualifier, e.g.:
v_map.emplace("A", &MyClass::a);
  1. When you invoke the method, you need to use the syntax for dereferencing a pointer to method:
(this->*function)(num);

See fixed version:

#include <string>
#include <unordered_map>
#include <iostream>

class MyClass
{
    typedef bool(MyClass::*fun)(int num);
public:
    MyClass() { MyClass_functionReg(); }
    ~MyClass() {}

    bool exec(std::string command)
    {
        fun function = find(command);
        (this->*function)(num);
        return true;
    }

private:
    std::unordered_map<std::string, fun> v_map;
    int num;
private:
    bool MyClass_functionReg()
    {
        v_map.emplace("A", &MyClass::a); // error here
        v_map.emplace("B", &MyClass::b);
        v_map.emplace("C", &MyClass::c);
        v_map.emplace("ERROR", &MyClass::c);
        return true;
    }

    fun find(std::string command)
    {
        if (v_map.find(command) != v_map.end())
        {
            return v_map[command];
        }
        else
        {
            return v_map["ERROR"];
        }
    }

    bool a(int num)
    {
        std::cout << "MyClass::a" << std::endl;
        return true;
    }
    bool b(int num)
    {
        std::cout << "MyClass::b" << std::endl;
        return true;
    }
    bool c(int num)
    {
        std::cout << "MyClass::c" << std::endl;
        return true;
    }
    bool error(int num)
    {
        std::cout << "MyClass::error" << std::endl;
        return true;
    }
};


int main(int argc, char** argv)
{
    MyClass t;
    t.exec("A");
    t.exec("B");
    return 0;
}

Output:

MyClass::a
MyClass::b

A side note: main is returning an int (not bool). Returning 0 means there were no errors. See: What should main() return in C and C++?.

wohlstad
  • 12,661
  • 10
  • 26
  • 39
  • I just noticed that you have `num` as a class member, so I removed my 4th point from my answer. – wohlstad Jul 22 '22 at 03:44
  • Actually,my exec method use the variable defined in class with private, so i didn't pass it as a parameter, i tried to add the class name before the function-pointer but i found i can't call it with function in exec method, i'm new to c++ – lavenderwha Jul 22 '22 at 03:48
  • Regarding `num` - see my comment above. I updated my answer after noticing that you have it as a member. – wohlstad Jul 22 '22 at 03:49