Вставить указатель функции в QMap (Qt)

Я создаю своего рода маршрутизатор для REST API в Qt, и у меня возникла проблема со вставкой указателя функции в QMap.

У меня есть класс IModule, из которого получены другие модули. Важные строки IModule.h

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

class IModule : public QObject
{
   Q_OBJECT

  protected:
    QMap<QString , IBusAction > *m_actions;

Затем у меня есть UserModule, который является производным от IModule, а в файле .cpp у меня есть эти строки:

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);

}

Итак, я попробовал два варианта, как поставить функцию в QMap со ссылочным знаком и без него, но оба не работают. Я получаю сообщение об ошибке: no matching function for call to 'QMap<QString, QByteArray* (*)(IBus*, ProxyRequest*)>::insert(const char [5], QByteArray* (UserModule::*)(IBus*, ProxyRequest*))'

Я потратил несколько часов на эту проблему, пробовал много разных способов ее решения, но безуспешно.

Так что буду очень рад любому совету.


person marek_lani    schedule 11.11.2012    source источник


Ответы (2)


Ваш IBusAction является типом указателя на функцию. Это несовместимо с функцией указателя на член.

Когда вы вызываете функцию-член (например, вашу функцию UserModule::create), ей нужен дополнительный ("невидимый") параметр: экземпляр, для которого вызывается функция (указатель this).

У вас есть по существу три варианта:

  • Измените IBusAction на указатель на функцию-член UserModule. Однако с этим вы ограничены функциями этого класса.

    typedef QByteArray* (UserModule::*IBusAction)(IBus * , ProxyRequest *);
    
  • Сделайте функции static (это изменит семантику вашего кода)

  • Используйте автономные функции (верхнего уровня, а не члены класса) вместо функций-членов.
person Mat    schedule 11.11.2012
comment
Поскольку UserModule является производным от IModule, который также определяет функции show и create, но они виртуальные, я пробовал typedef QByteArray* (IModule::*IBusAction)(IBus *, ProxyRequest *); Но он не работал, и я не знаю, почему. - person marek_lani; 11.11.2012
comment
извините, я отредактировал свой комментарий выше, потому что в середине написания я случайно нажал ввод - person marek_lani; 11.11.2012
comment
Так тоже не сработает, указатель на функцию-член производного класса несовместим с указателем на член базы. (Вы не можете вызвать производную функцию для базового объекта, хотя работает и наоборот.) - person Mat; 11.11.2012
comment
Хорошо, это плохие новости, но большое спасибо за помощь :)) - person marek_lani; 11.11.2012

Указатели на функции-члены в C++ обычно доставляют больше хлопот, чем пользы. Разумной альтернативой является использование класса вместо метода и сохранение указателя на экземпляр вместо метода.

Конкретной альтернативой Qt является использование вызываемых методов класса на основе QObject, которые вы можете вызывать по строковому имени, используя QObject::invokeMethod, обходя многие проблемы с типами.

person hyde    schedule 11.11.2012