user2883136
user2883136

Reputation:

C++ Creating a vector of function pointers inside a map

So I have this class which is supposed to allow any other class to link their member functions to be called when an event happens (i.e a class could have one function linked to an arrow key press and a separate function linked to the spacebar), and I'm attempting to do this using a map, like so:

std::unordered_map<SDL_Event, std::vector<void(*)(void)>> Callbacks;

However this is giving this error:

C2280   'std::hash<_Kty>::hash(const std::hash<_Kty> &)': attempting to reference a deleted function    

The rest of the error information isn't helping since it points to a blank function in the definition for unordered_map (line 132):

unordered_map()
    : _Mybase(key_compare(), allocator_type())
    {   // construct empty map from defaults
    }

From what I'm able to understand the problem is that the unordered_map is trying to perform a hash on an empty function pointer for some reason and it's failing for obvious reasons.

I'm completely stuck as to what I can do as a solution to this that wouldn't involve writing my own version of a map, which I'd rather not do.

Upvotes: 0

Views: 155

Answers (2)

HolyBlackCat
HolyBlackCat

Reputation: 96924

this class which is supposed to allow any other class to link their member functions to be called when an event happens

In addition to the event type, SDL_Event contains a lot of information that you don't need, such a timestamp of when the event happened.

Since the only thing you need is the event type, you should use SDL_EventType enum as a key:

std::unordered_map<SDL_EventType, std::vector<void(*)(void)>> Callbacks;

Since it's a simple enum, you don't need to define a custom comparator for it.

Upvotes: 0

In order to use SDL_Event as key type for a std::map (ordered) you should provide your custom "less than" function that tells how to order two SDL_Event.

In order to use SDL_Event as key type for a std::unordered_map you should provide your custom "equal" function that tells how to differentiate two SDL_Event and you should provide your custom hash function that tells how to compute a hash value from a SDL_Event, this hash value should be equal for two SDL_Event that are equals according to your equal function, you can use std::hash applyed and combined to some fields of the SDL_Event structure.

The simpler way in to use a map with less than operator for SDL_Event :

#include <map>
#include <vector>
#include <SDL/SDL_events.h>

using namespace std;

inline bool operator<(const SDL_KeyboardEvent& lhs,
                      const SDL_KeyboardEvent& rhs)
{
    return lhs.keysym.sym < rhs.keysym.sym;
}

inline bool is_keyevent(const SDL_Event& ev)
{
    return ev.type == SDL_KEYDOWN || ev.type == SDL_KEYUP;
}

inline bool operator<(const SDL_Event& lhs, const SDL_Event& rhs)
{
    return lhs.type < rhs.type ||
           lhs.type == rhs.type && is_keyevent(lhs) && lhs.key < rhs.key;
}

map<SDL_Event, vector<void(*)(void)>> Callbacks;

Note that the less than operator in this example provide two different entries for KEYDOWN and KEYUP.

Upvotes: 1

Related Questions