1

I am creating sort of a router for REST API in Qt and I am facing problem with inserting the function pointer into the QMap.

I have class IModule from which the other modules are derivated. Important lines of IModule.h are

typedef QByteArray* (*IBusAction)(IBus * , ProxyRequest *);

class IModule : public QObject
{
   Q_OBJECT

  protected:
    QMap<QString , IBusAction > *m_actions;

Then I have UserModule which is derived from IModule and in .cpp file I have these lines:

QByteArray* UserModule::create(IBus *bus, ProxyRequest *req)
{
}

QByteArray* UserModule::show( IBus *bus, ProxyRequest *req)
{
}


UserModule::UserModule(QObject *parent) :
IModule(parent)
{

    // register functions
    m_actions->insert("show", &UserModule::show);
    m_actions->insert("create", UserModule::create);

}

So I tried two options how to put the function in QMap with referencing sign also without it, but both are not working. I am getting error: no matching function for call to 'QMap<QString, QByteArray* (*)(IBus*, ProxyRequest*)>::insert(const char [5], QByteArray* (UserModule::*)(IBus*, ProxyRequest*))'

I have spent several hours with this problem, tried many different things how to solve it but there was no success.

So I will be very glad for any piece of advice.

stealthyninja
  • 10,343
  • 11
  • 51
  • 59
marek_lani
  • 3,895
  • 4
  • 29
  • 50

2 Answers2

2

Your IBusAction is a pointer-to-function type. This is not compatible with pointer-to-member function.

When you call a member function (like your UserModule::create function), it needs an extra ("invisible") parameter: the instance the function gets called on (the this pointer).

You have essentially three options:

  • Change IBusAction to be a pointer-to-member-function-of-UserModule. You're restricted to that class's functions with this though.

    typedef QByteArray* (UserModule::*IBusAction)(IBus * , ProxyRequest *);
    
  • Make the functions static (this changes the semantics of your code)

  • Use free-standing functions (top-level, not members of a class) instead of member functions.
Mat
  • 202,337
  • 40
  • 393
  • 406
  • As the UserModule is derivated from IModule which also defines functions show and create but they are virtual, I have tried typedef QByteArray* (IModule::*IBusAction)(IBus * , ProxyRequest *); But it was not working and I don't know why. – marek_lani Nov 11 '12 at 12:08
  • sry i edited my above comment because in the middle of writing I accidentally pressed enter – marek_lani Nov 11 '12 at 12:11
  • Won't work that way either, a pointer to a member function of the derived class is not compatible with a pointer to member of the base. (You can't call a derived function on a base object; the other way around works though.) – Mat Nov 11 '12 at 12:13
  • Ok these are the bad news, but thank you very much for help :)) – marek_lani Nov 11 '12 at 12:15
0

Pointers to member functions in C++ is generally more hassle than it is worth. Sane alternative is to have class instead of method, and keep pointer to instance instead of method.

Qt specific alternative is to use invokable methods of QObject based class, which you can call by string name, using QObject::invokeMethod, side-stepping many type problems.

hyde
  • 60,639
  • 21
  • 115
  • 176