1

我正在尝试QSet用于存储函数指针列表。有关更多详细信息,请参阅此代码。问题是这段代码不能由 gcc/mingw 编译。MSVC 正常编译它。我究竟做错了什么?

typedef intptr_t (*UikHook)(intptr_t);
...
typedef struct
{
    QSet<UikHook>*  qsetSubscribers;
    //QMutex*           qmutexHook;
} THookableEvent;
...
THookableEvent* p = qmapHooks_.value(name);
if (p->qsetSubscribers == 0)
    p->qsetSubscribers = new QSet<UikHook>();
p->qsetSubscribers->insert(hookProc);

error: no matching function for call to ‘qHash(long int (* const&)(long int))’

也许,我应该像文档中所说的那样为类型声明operator==和函数,但我不知道该怎么做,因为当我声明时,我收到以下错误:qHash()UikHookopertator==

inline bool operator==(const UikHook &e1, const UikHook &e2)

error: ‘bool operator==(intptr_t (* const&)(intptr_t), intptr_t (* const&)(intptr_t))’ 
must have an argument of class or enumerated type

PS 我正在使用 Qt 5.8、gcc 6.2、msvc2015

更新:通过将 QSet 替换为 QVector 解决。

4

3 回答 3

2

您不能operator==为内置类型定义 an,例如指针、整数或浮点数。他们已经有了。您只需要提供一个qHash.

于 2017-01-25T13:02:31.320 回答
1

使用函数指针并不是 C++ 中的最佳实践。在早期的 C++ 版本中,改为使用仿函数。从 C++11 开始,就有了真正的函数对象。std::function()您可以通过( Reference )将函数指针转换为对象。

如果您列出的编译器是您需要支持的编译器,我强烈建议您使用std::function而不是函数指针。

于 2017-01-25T13:04:54.240 回答
0

尝试(警告,大脑编译):

template <typename R, typename ...A>
inline uint qHash(R (*)(A...) const f) noexcept
{
  return std::hash<R (*)(A...)>()(f);
}

Qt 在这里进行了修复,因为它不能使用 STL 并且散列函数指针在某种程度上是特定于编译器的。

于 2017-01-26T08:26:49.177 回答