0

I am getting the error term does not evaluate to a function taking 1 arguments when trying to call a function pointer.

The function pointer is stored in a struct. The struct is then stored in a map. Definition:

typedef void (CLIOptions::*OptionHandler)(QString);

struct OptionDefinition {
   QString name;
   QString description;
   QString type;
   OptionHandler handler;
};

typedef std::map<QString, OptionDefinition> CLIOptionMap;

I initialise the map like this:

CLIOptionMap optionMap =
{
   {
      QString("set-tcp-host"),
      {
         QString("set-tcph"),
         QString("Set the TCP server host address"),
         QString("string"),
         &CLIOptions::setTcpHost
      }
   },
  // etc...
}

The problem occurs when I try to iterate through the map and call the handler:

for (it = optionMap.begin(); it != optionMap.end(); ++it) {
    QString value = /*snip...*/

    (it->second.handler)(value)
}

What is my problem here?

jramm
  • 6,415
  • 4
  • 34
  • 73
  • How would the line of code you wrote know what instance of CLIOptions to call that member function on? – Mat Jan 05 '18 at 09:57
  • duplicate of https://stackoverflow.com/questions/1485983/calling-c-class-methods-via-a-function-pointer me thinks – UKMonkey Jan 05 '18 at 09:57
  • @EdgarRokyan : No. `it->second.handler` is the pmf. You then need something like `this->*(it->second.handler)(value)`. This is complicated enough, I recommend an intermediate variable for readability. – Martin Bonner supports Monica Jan 05 '18 at 10:01

1 Answers1

3

Your problem is that you don't have a function pointer, you have a pointer to member function, and they are very different beasts. A pointer-to-member-function isn't even a pointer in general (it has to be able to handle pointer to a virtual function in a second virtual base class!)

Given you have a pmf, you need an object to invoke the pmf on. So something like:

for (it = optionMap.begin(); it != optionMap.end(); ++it) {
    QString value = /*snip...*/
    const auto pmf = it->second.handler;
    (mOptionHandler.*pmf)(value);
}

actually, if you going to use C++11 auto, you can also use the foreach loop:

for (const auto& option : optionMap) {
   const auto pmf = option.handler;
   (mOptionHandler.*pmf)(option.value);
}