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?

3
  • How would the line of code you wrote know what instance of CLIOptions to call that member function on? Commented Jan 5, 2018 at 9:57
  • duplicate of stackoverflow.com/questions/1485983/… me thinks Commented Jan 5, 2018 at 9: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. Commented Jan 5, 2018 at 10:01

1 Answer 1

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);
}
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks. So I have an instance of "CLIOptions" available called mOptionHandler, so I setup the call like (mOptionHandler.pmf) but this gives CLIOptions has no member pmf
Oh I just missed a dereference I think: mOptionHandler.*pmf
I've changed my example to use your name. And yes - the .* operator is completely different to the . operator!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.