0

I thought that std::hash's specialization for generic pointer types can be used for pointer-to-members, however I am unable to use it as such; instead, my compiler gives me an "incomplete type" error, which I assume means that is' not using the specialization of std::hash for pointers? What's going on here?

#include <functional>

struct foo{
    void bar(int a){}
};

int main(){
    std::hash<void (foo::*)(int)> hasher;
}

The error:

..\src\m.cpp:43:32: error: aggregate 'std::hash<void (foo::*)(int)> hasher' has incomplete type and cannot be defined

3 Answers 3

3

The trouble is that pointers to member are not really pointers; they just happen to have a similar name and kind of similar syntax. std::hash is specialized for ordinary pointers, but not for pointers to members. You could of course specialize it yourself, but if there's a way to do that that's guaranteed to be safe, I'm not seeing it; there's not much you can do with a pointer to member other than dereference it or cast it to other pointers to members.

1
  • Worth remembering: they are not pointers (demo). I would add one thing the end of your list of what we can do with them: we can compare them with ==, which begs for the question why are they not hashable in the language.
    – Dr. Gut
    Commented 3 hours ago
1

change the struct declaration to:

struct foo{
    static void bar(int a){}
};

Non-static member functions have a hidden parameter that corresponds to the this pointer, that's why the compiler happens.

1
  • It is critical that I take the hash of a pointer-to-member, rather than a static function.
    – Shokwav
    Commented Nov 27, 2014 at 1:21
0

You have to define the specialization before you can use it.

namespace std
{
   template <>
   struct std::hash<void (foo::*)(int)>
   {
       // Implement the class.
   };
}

Use it.

int main(){
    std::hash<void (foo::*)(int)> hasher;
}
4
  • That "Implement the class" glosses over the hard part of the problem- it's far from clear how to compute a hash value for a pointer-to-member. Commented Nov 26, 2014 at 22:30
  • @GeoffRomer, I agree. I am not sure the OP knows how to implement the class either. I was helping to explain the compiler error and how to overcome that.
    – R Sahu
    Commented Nov 26, 2014 at 22:34
  • @R Sahu as far as I know, there is no well-defined way to take the hash of a pointer-to-member. I was just (incorrectly) assuming that the pointer specialization of std::hash covered them.
    – Shokwav
    Commented Nov 27, 2014 at 1:02
  • @Shokwav, Perhaps the answer to this SO post might help. stackoverflow.com/questions/1328238/…
    – R Sahu
    Commented Nov 27, 2014 at 1:57

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.