Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function and method pointers in a std::set

As described in another message of mine, it is not possible to compare 2 pointers to member functions with "<" (less than). Or at least, this causes undefined behavior.

I have just managed to compile this code both with Visual C++ as well as GCC:

template <class Receiver, class Param = void*, class Return = void>
class EventReceiver : public IFunction<> {

protected:

    std::set< Return(Receiver::*)(Param) > test;
    std::set< Return(*)(Param) > test2;
...

AFAIK, to make a std::map or std::set of anything, it must be possible to compare the set's values with "<". Does this mean that the above containers or the actual compilers have a working implementation of comparing pointers-to-methods in such a way?

like image 220
Bill Kotsias Avatar asked Nov 13 '22 10:11

Bill Kotsias


1 Answers

Well, it was in reality misleading that the example code compiled. The truth is that the sets are unusable. Every attempt to insert data into them produces the expected error.

That's the "dark side" of C++ template functions. They don't exist till you use them (and thus won't produce compiler errors till you do).

Check this out :

#include <set>

class X {};

int main() {

    typedef void(X::*FuncPtr)();
    std::set< FuncPtr > set;
    std::less< FuncPtr > less;
    FuncPtr f1;
    FuncPtr f2;
    //set.insert(f1);   // both of these lines
    //less(f1,f2);      // produce an error
};

Removing the comments in any of the last 2 lines produces the error :

invalid operands of types ‘void (X::* const)()’ and ‘void (X::* const)()’ to binary ‘operator<’

Compile it online yourself here.

like image 96
Bill Kotsias Avatar answered Nov 29 '22 04:11

Bill Kotsias