我正在尝试使用模板实现通用事件处理系统,但是当我尝试将该函数添加到列表时,我在编译时遇到错误。
错误C2298:缺少对成员函数的绑定指针的调用
class EventManager
{
public:
template <class OBJECT>
void subscribe(std::string eventName, OBJECT *obj, void(OBJECT::*newEvent)(Event))
{
(obj->*newEvent)(Event()); // I can call the event just fine if I execute it alone
abc.push_back(obj->*newEvent); // Error c2298 here
}
static EventManager* Get();
private:
std::vector<void(*)(Event)> eventsList;
};
这就是我所说的:
EventManager::Get()->subscribe("EventName", this, &TestClass::eventTest);
void ATideManager::eventTest(Event event)
{
//Test
}
我对C ++和模板很陌生,所以我确信解决方案很简单,但我不明白为什么我可以调用该事件但不将其添加到向量中。你知道我怎么可能这样做吗?
答案 0 :(得分:1)
obj->*newEvent
无效。成员函数指针只能以这种方式用于调用指向成员函数。
但您可以使用std::vector<std::function<void(Event)>>
和
abc.push_back(std::bind(newEvent, obj, std::placeholders::_1);
答案 1 :(得分:1)
正如documentation for that error message所说:
指向成员函数表达式的指针必须调用成员函数。
换句话说,你不能存储一个指向成员函数的指针,包括要调用它的对象,供以后使用。
以下是使用与您类似的名称的简单示例:
struct Object
{
void f() {}
};
int main()
{
Object obj;
using member_function_pointer = void (Object::*)();
member_function_pointer ptr = &Object::f;
(obj.*ptr)();
(obj.*ptr); // error
}
这很有道理。你的abc
可能是成员函数指针的向量(或者只是函数指针的向量);它不能神奇地存储一个对象以及每个指针。
通常,指向成员函数的指针并不是C ++中最好,最干净或最好的特性,而且糟糕的语法使得使用它的每一段代码都完全不可读。幸运的是,C ++ 11引入了 std::function
和lambdas ,这为您提供了更好的选择:
#include <functional>
#include <iostream>
#include <string>
#include <vector>
struct Event
{
int i;
};
class EventManager
{
public:
void subscribe(std::string const& eventName,
std::function<void(Event const&)> event)
{
abc.push_back(event);
}
static EventManager& get()
{
static EventManager instance;
return instance;
}
void onEvent(Event const& event)
{
for (auto&& f : abc)
{
f(event);
}
}
private:
EventManager() {}
EventManager(EventManager const&) = delete;
EventManager& operator=(EventManager const&) = delete;
std::vector<std::function<void(Event const&)>> abc;
};
struct ATideManager
{
void f()
{
EventManager::get().subscribe("EventName",
[=](Event const& event) { eventTest(event); });
}
void eventTest(Event const& event)
{
std::cout << "eventTest: " << event.i << "\n";
}
};
int main()
{
ATideManager manager;
manager.f();
Event some_event{ 123 };
EventManager::get().onEvent(some_event);
}
我还修复了你不必要地使用可以使用引用的指针,以及一些const
- 正确性问题。