1

I'm trying to use QSet for storing a list of function pointers. See this code for more details. The problem is that this code does not compile by gcc/mingw. MSVC compiles it normally. What am I doing wrong?

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

Perhaps, I should to declare operator== and function qHash() for type UikHook as it said in the docs, but I dont know how to do it because when I'm declaring opertator==, I get the following error:

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

P.S. I'm using Qt 5.8, gcc 6.2, msvc2015

Update: Solved by replacing QSet to QVector.

Sergey
  • 144
  • 1
  • 13
  • 2
    BTW, `typedef struct {` is C, not C++. In C++ it's just `struct THookableEvent {`. This is important because you otherwise can't define a ctor. – MSalters Jan 25 '17 at 13:25

3 Answers3

2

You can't define an operator== for built-in types, such as pointers, integers or floating-point numbers. They already have it. You just need to provide a qHash.

MSalters
  • 173,980
  • 10
  • 155
  • 350
  • Same question as comment above. How to write correct qHash function? My try does not work. `inline uint qHash(const UikHook& key, uint seed = 0) { return reinterpret_cast(key); }` – Sergey Jan 25 '17 at 13:18
  • @Sergey: Why not? Have you googled the error you get? – MSalters Jan 25 '17 at 13:26
  • Same error: no matching function for call to ‘qHash(long int (* const&)(long int))’ – Sergey Jan 25 '17 at 13:31
1

Using function pointers is not really the best practice in C++. In early C++ versions, functors were used instead. Since C++11, there are real function objects. You can convert a function pointer to an object via std::function() (Reference).

If the compilers you listed are the ones you need to support, I strongly suggest using std::function instead of function pointers.

ypnos
  • 50,202
  • 14
  • 95
  • 141
  • Okay, but how to write a correct qHash function for std::function? – Sergey Jan 25 '17 at 13:15
  • 1
    Well, maybe the set is not the right container for you to use? How do you access these functions after storing them? Just iterating through? Then you should use `QVector` or `QList`. – ypnos Jan 25 '17 at 15:30
0

Try (warning, brain compile):

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

Qt is in a fix here, since it can't use the STL and hashing function pointers is somewhat compiler specific.

user1095108
  • 14,119
  • 9
  • 58
  • 116