std::bind to void* to std::function
std::bind to void* to std::function
我正在尝试制作一个事件系统 该系统的用户必须执行此操作才能为输入添加事件,例如:
addEventHandler(Event::KEYBOARD_INPUT, reinterpret_cast<void*>(&std::bind(&Game::On_Input, this)));
传递的函数将在触发事件时调用,这些函数存储在 std::vectors 中,到目前为止没有问题。但是不同的事件有不同的函数签名。 由于 std::function 本身就是一种类型,我不能让这个函数接受我试图将 std::bind 转换为 void* 的所有事件,然后将其转换回 std::function,但它不起作用,因为 impl 未定义 (0xCCCCCCCC(
当前代码:
void EventManager::addEventHandler(Event event, void* p_Fun)
{
if (event == Event::KEYBOARD_INPUT) {
m_InputCallbacks.push_back(*reinterpret_cast<std::function<void(Keycode, unsigned int)>*>(p_Fun));
}
/*else if(...){ // other events other push backs in other vectors
}*/
}
并且存储的函数调用如下:
void EventManager::HandleEvents(SDL_Event& Event)
{
while (PollEvent(&Event) != 0) {
if (Event.type == KEYDOWN || Event.type == KEYUP) {
//On_Input(Event.key.keysym.sym, Event.type);
for (auto inputCallbackFunc : m_InputCallbacks) {
inputCallbackFunc(Event.key.keysym.sym, Event.type);//CRASH HERE!
}
}
}
}
请注意,此版本仅处理输入,我不知道将来会添加多少事件(碰撞,多人游戏连接等(,这就是为什么我想通过addEventHandler函数自动执行处理,该函数将检查以下内容: 1( 事件类型是什么,并将 void 函数指针强制转换为该事件回调函数签名 2(将它们存储在适当的std::vector中
那么总而言之,如何使 AddEventHandler 接受传递给它的每一个 std::bind 可以存储和稍后调用?
>std::function
提供了存储具有将用于调用它的签名的单个类型的std::vector
所需的所有类型擦除。没有必要被选角来void*
为了简单起见,这样的东西就是你想要的。
#include <iostream>
#include <vector>
#include <functional>
#include <type_traits>
using namespace std;
enum Event
{
KEYBOARD_INPUT,
MOUSE_INPUT
};
std::vector< std::function<void(int,int)> > keyboard_handlers;
std::vector< std::function<void(int,int,int)> > mouse_handlers;
template <Event EventType,typename Func,
typename std::enable_if<EventType==KEYBOARD_INPUT,bool>::type=true>
void addEventHandler(Func&& func)
{
keyboard_handlers.push_back(
std::function<void(int,int)>(std::forward<Func>(func)));
}
template <Event EventType,typename Func,
typename std::enable_if<EventType==MOUSE_INPUT,bool>::type=true>
void addEventHandler(Func&& func)
{
mouse_handlers.push_back(
std::function<void(int,int,int)>(std::forward<Func>(func)));
}
void call_keyboard_handlers(int a,int b)
{
for (auto inputCallbackFunc : keyboard_handlers) {
inputCallbackFunc(a,b);
}
}
void keyboard_callback_1(std::string name, int a , int b)
{
std::cout << "keyboard_callback_1 " << name << " " << a << " " << b << std::endl;
}
void keyboard_callback_2(int a , int b)
{
std::cout << "keyboard_callback_2 " << a << " " << b << std::endl;
}
struct keyboard_callback_3_type
{
void operator()(int a,int b)
{
std::cout << "keyboard_callback_3 " << a << " " << b << std::endl;
}
};
int main() {
//With an extra bound in string argument.
addEventHandler<KEYBOARD_INPUT>(std::bind(&keyboard_callback_1,"somestring",std::placeholders::_1,std::placeholders::_2));
//From a plain function pointer
addEventHandler<KEYBOARD_INPUT>(&keyboard_callback_2);
//From a memberfunction pointer
keyboard_callback_3_type keyboard_callback_3;
addEventHandler<KEYBOARD_INPUT>(std::bind(&keyboard_callback_3_type::operator(),&keyboard_callback_3,std::placeholders::_1,std::placeholders::_2));
//From a non capturing lambda
addEventHandler<KEYBOARD_INPUT>([](int a,int b){ std::cout << "lambda_callback " << a << " " << b <<std::endl;});
std::string capture = "Captured";
//From a capturing lambda
addEventHandler<KEYBOARD_INPUT>([&](int a,int b){ std::cout << "lambda_callback " << capture << " " << a << " " << b <<std::endl;});
call_keyboard_handlers(10,20);
return 0;
}
演示
请注意,如果要将函数名称保留为 addEventHandler,则必须根据事件类型启用函数的不同变体(如示例中所示(,或者以不同的方式命名它们(即 addKeyboardEventHandler、addMouseEventHandler 等(。
相关文章:
- std::bind to void* to std::function
- std::time_point from and to std::string
- "No suitable conversion function from 'std::string' to 'const char *' exists"
- Port pthread_cond_broadcast to std::atomic
- from std::vector to adept::avector
- File to std::string_view
- 如何修复以下错误"no match for call to '(std::tr1::shared_ptr<_iobuf*>) (FILE*&)'"
- std::map to std::list leads to SIGSEGV
- std::bind to a std::variant 包含多个 std::函数类型
- NSMutableArray to std::vector
- 将 2D 数组插入 std::vector 时"cannot convert from 'const GLfloat [12]' to '_Objty'"错误消息
- 使用 std::min "no matching function for call to ‘min(<brace-enclosed initializer list>)’"时出错
- 返回"Cannot convert from 'std::ofstream {aka std::basic_ofstream<char>}' to bool"错误
- reinterpret_cast std::function* to and from void*
- std::string to std::regex
- 使用命名空间 std 时C++ "Reference to overloaded function"错误
- Copy std::vector to boost::interprocess::vector
- BOOST :: lexical_cast to std ::字符串失败
- C++ std::vector to JSON Array with rapidjson
- 最快的方式 std::vector<Derived> to std::vector<Base>