提问人:guyus15 提问时间:10/13/2022 更新时间:10/13/2022 访问量:70
有没有办法将派生自同一碱基的不同类型的 std::函数存储在单个向量中?
Is there a way to store std::functions of different types derived from the same base in a single vector?
问:
我知道以前有人问过这样的问题,但我还没有找到适合我具体情况的答案。
这里是:我正在尝试构建一个事件系统,程序员可以在其中创建事件,这些事件可以由事件管理器广播并由事件侦听器监听。每个事件都派生自一个公共基类。GameEvent
#pragma once
#include <string>
struct GameEvent
{
std::string name = "Game Event";
};
// Events
struct StartEvent : GameEvent
{
std::string msg = "This is the start event!";
};
struct EndEvent : GameEvent
{
std::string msg = "This is the end event";
};
struct Events
{
static const StartEvent s_StartEvent;
static const EndEvent s_EndEvent;
};
const StartEvent Events::s_StartEvent;
const EndEvent Events::s_EndEvent;
// Custom hash function for GameEvent.
struct GameEventHash
{
std::size_t operator()(const GameEvent& evt) const
{
return std::hash<std::string>()(evt.name) << 1;
}
};
// Custom equal function for GameEvent.
struct GameEventEqual
{
bool operator()(const GameEvent& t1, const GameEvent& t2) const {
return t1.name == t2.name;
}
};
为了将与事件的关联存储到它们的侦听器,我正在尝试使用 s 到 s 向量的无序映射。这可以看作是类的静态成员。GameEvent
std::function
EventManager
#pragma once
#include "events.h"
#include <functional>
#include <unordered_map>
#include <vector>
struct EventManager
{
template<typename T>
static void AddListener(std::function<void(T)> listener);
static void Broadcast(GameEvent evt);
private:
static std::unordered_map<GameEvent, std::vector<std::function<void(GameEvent)>>, GameEventHash, GameEventEqual> s_Events;
};
inline void EventManager::Broadcast(GameEvent evt)
{
for (std::function<void(GameEvent)> listener : s_Events[evt])
{
listener(evt);
}
}
template<typename T>
void EventManager::AddListener(std::function<void(T)> listener)
{
T evt;
// Add function to map of events to listeners.
auto iter = s_Events.find(evt);
// If event already has listeners
if (iter != s_Events.end())
{
// Add to the vector of listeners.
std::vector<std::function<void(GameEvent)>>& listeners = s_Events[evt];
listeners.push_back(listener);
}
else
{
// Insert new vector with listener.
s_Events[evt] = std::vector<std::function<void(GameEvent)>>{listener};
}
}
std::unordered_map<GameEvent, std::vector<std::function<void(GameEvent)>>, GameEventHash, GameEventEqual> EventManager::s_Events;
我遇到的问题是类的方法。因为事件的无序映射的向量采用以下类型的函数 ,尝试在模板中使用任何其他类型都会导致错误。有问题的错误是:AddListener
EventManager
GameEvent
EventSystem\EventSystem\event-manager.h(40,12): error C2664: 'void std::vector<std::function<void (GameEvent)>,std::allocator<std::function<void (GameEvent)>>>::push_back(const _Ty &)': cannot convert argument 1 from 'std::function<void (StartEvent)>' to 'const _Ty &'
和
EventSystem\EventSystem\event-manager.h(45,62): error C2440: '<function-style-cast>': cannot convert from 'initializer list' to 'std::vector<std::function<void (GameEvent)>,std::allocator<std::function<void (GameEvent)>>>'
我了解我的问题,但我不明白如何解决它。有人可以提供解决方案或替代建议吗?
答: 暂无答案
评论
EventManager::AddListener
在目前的状态下似乎相当嘈杂和多余。该功能的全部内容可以实现为s_events[T{}].push_back(listener);
listeners