如何声明一个带指针到成员函数的函数

时间:2018-01-25 12:26:53

标签: c++ qt function-pointers

我有一个类,其成员变量指向库对象。

class myClassA {
private:
    libraryClass *libraryObject;
}

库类发出以字符串为特征的事件,并提供一种机制,允许客户端类指定在发出事件时应调用的成员函数,因此在 myClassA 中,我可以做到

libraryObject->connect ("eventName", this, &myClassA::privateMember);

我现在希望 myClassA 的客户能够将其成员函数连接到事件,方法是将公共成员函数 connect 添加到 myClassA < / em>的。我应该如何在 myClassA 头文件中声明 connect

具体来说,我正在使用Qt并尝试允许客户端( myClassA )调用 QScxmlStateMachine :: connectToEvent 。此函数的Qt documentation将其描述为

QMetaObject::Connection QScxmlStateMachine::connectToEvent(
            const QString &scxmlEventSpec,
            const QObject *receiver,
            PointerToMemberFunction method,
            Qt::ConnectionType type = Qt::AutoConnection)

但我不清楚应该如何定义 PointerToMemberFunction

Qt头文件将其声明为

template <typename Func1>
QMetaObject::Connection connectToEvent(
        const QString &scxmlEventSpec,
        const typename QtPrivate::FunctionPointer<Func1>::Object *receiver, Func1 slot,
        Qt::ConnectionType type = Qt::AutoConnection);

而不是我只是盲目地将其复制到我的代码中并查看它是否有效,请有人向我解释这个声明;特别是我读到它说有些东西是模板化的,我不明白是什么,为什么我不需要做任何模板-y来使用这个机制。

感谢。

2 个答案:

答案 0 :(得分:2)

QtPrivate::FunctionPointer是一种类型特征模板,可以帮助新的Qt信号/插槽语法。

  

How Qt Signals and Slots Work - Part 2 - Qt5 New Syntax

     

类型特征:QtPrivate::FunctionPointer

     

特征基本上是一个辅助类,它提供有关给定元数据的元数据   类型。 Qt中另一个特征的例子是QTypeInfo

     

为了实现新语法,我们需要知道的是   有关函数指针的信息。

     

template<typename T> struct FunctionPointer会给我们   有关T通过其成员的信息。

     
      
  • ArgumentCount:一个整数,表示函数的参数个数。

  •   
  • Object:仅存在指向成员函数的指针。它是函数所属类的typedef。

  •   
  • Arguments:表示参数列表。它是元编程列表的typedef。

  •   
  • call(T &function, QObject *receiver, void **args):一个静态函数,它将调用函数,应用给定的参数。

  •   
     

...

     

FunctionPointer的实施位于qobjectdefs_impl.h

此特征允许根据提供的参数选择正确的QScxmlStateMachine::connectToEvent - QObject槽,仿函数或函数指针(包含或不包含上下文)。

// connect state to a QObject slot
template <typename Func1>
inline QMetaObject::Connection connectToEvent(
        const QString &scxmlEventSpec,
        const typename QtPrivate::FunctionPointer<Func1>::Object *receiver, Func1 slot,
        Qt::ConnectionType type = Qt::AutoConnection)


// connect state to a functor or function pointer (without context)
template <typename Func1>
inline typename QtPrivate::QEnableIf<
        !QtPrivate::FunctionPointer<Func1>::IsPointerToMemberFunction &&
        !std::is_same<const char*, Func1>::value, QMetaObject::Connection>::Type
connectToEvent(const QString &scxmlEventSpec, Func1 slot,
               Qt::ConnectionType type = Qt::AutoConnection)

// connectToEvent to a functor or function pointer (with context)
template <typename Func1>
inline typename QtPrivate::QEnableIf<
        !QtPrivate::FunctionPointer<Func1>::IsPointerToMemberFunction &&
        !std::is_same<const char*, Func1>::value, QMetaObject::Connection>::Type
connectToEvent(const QString &scxmlEventSpec, QObject *context, Func1 slot, Qt::ConnectionType type = Qt::AutoConnection)

因此,如果您需要允许所有情况,您可以使用相同的原型提供方法并转发参数。

答案 1 :(得分:2)

完成所有各种包含文件,同时制定问题可以解决此问题。

我在 myClassA

的头文件中包含以下内容
template <typename Func1>           // Lifted from QtScxmlStateMachine.h
QMetaObject::Connection connectToEvent(
        const QString &scxmlEventSpec,
        const typename QtPrivate::FunctionPointer<Func1>::Object *receiver, Func1 slot,
        Qt::ConnectionType type = Qt::AutoConnection) {
    return libraryObject->connectToEvent(scxmlEventSpec, receiver, slot, type);
};

myClassA 的客户端现在可以调用 myClassA :: connectToEvent 来调用基础 QtScxmlStateMachine connectToEvent member。

谢谢你,StackOverflow,强迫我按顺序正确地理解我的想法。