如何声明一个带有指向成员函数的函数
Posted
技术标签:
【中文标题】如何声明一个带有指向成员函数的函数【英文标题】:How to declare a function that takes a pointer-to-member function 【发布时间】:2018-01-25 12:26:53 【问题描述】:我有一个类,其成员变量指向库对象。
class myClassA
private:
libraryClass *libraryObject;
库类发出事件,以字符串为特征,并提供一种机制,允许客户端类指定在事件发出时应调用的成员函数,所以在myClassA中,我可以的
libraryObject->connect ("eventName", this, &myClassA::privateMember);
我现在希望 myClassA 的客户能够通过将公共成员函数 connect 添加到 myClassA。我应该如何在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 来使用该机制。
谢谢。
【问题讨论】:
使用模板,就像所有standard C++ algorithm functions 使用谓词一样?还是std::function
?这些中的任何一个都将使您的生活更轻松。 :)
如果您需要调用 QScxmlStateMachine::connectToEvent 函数,那么您应该使用相同类型的参数。只需使用 PointerToMemberFunction 作为类型。 connectToEvent 期望接收此类型的第三个参数。
【参考方案1】:
在提出问题的同时浏览所有各种包含文件使我能够解决此问题。
我在 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 成员.
谢谢你,***,是你强迫我正确地整理自己的想法。
【讨论】:
【参考方案2】:QtPrivate::FunctionPointer
是一个类型特征模板,有助于新的 Qt 信号/槽语法。
How Qt Signals and Slots Work - Part 2 - Qt5 New Syntax
类型特征:
QtPrivate::FunctionPointer
特征基本上是一个帮助类,它提供有关给定的元数据 类型。 Qt 中 trait 的另一个例子是
QTypeInfo
。为了实现新语法,我们需要知道的是 关于函数指针的信息。
template<typename T> struct FunctionPointer
会给我们 有关T
的信息,请通过其成员。
ArgumentCount
:一个整数,表示函数的参数个数。
Object
:仅针对指向成员函数的指针存在。它是函数所属类的 typedef。
Arguments
:表示参数列表。它是元编程列表的 typedef。
call(T &function, QObject *receiver, void **args)
:一个静态函数,将调用该函数,应用给定的参数。...
FunctionPointer
的实现在于qobjectdefs_impl.h。
此 trait 允许根据提供的参数选择正确的 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)
因此,如果您需要允许所有情况,您可以提供具有相同原型的方法并转发参数。
【讨论】:
以上是关于如何声明一个带有指向成员函数的函数的主要内容,如果未能解决你的问题,请参考以下文章