我看到类似的问题之前在SO上被问过,但我看到的那些似乎不完全涉及我的使用情况。具体来说,我想知道我的编译失败是错误的结果,还是我试图做的被禁止的结果。
背景
我希望实现委托模式,用于处理事件。我认为,对于我的需求,最好的方法可能是一个成员函数指针的映射,由std::string(表示事件类型)索引。
我开始尝试使用std::function来实现这一点,但遇到了一些问题,然后决定仅使用原始MFPs重试。(我仍然愿意考虑使用std::function,并且我将接受一个向下面展示如何使用该方法实现我的确切需求的答案。但我仍然想知道我的当前方法有什么问题。)
我能够让这个方法在单个类中工作。但是我实际上希望委托映射由抽象基类提供,然后派生类将其委托注册到该映射中。除非我在下面的代码中犯了一些错误,否则这似乎是不可能的;似乎成员函数指针不能是多态的。
我得到的编译错误如下:
背景
我希望实现委托模式,用于处理事件。我认为,对于我的需求,最好的方法可能是一个成员函数指针的映射,由std::string(表示事件类型)索引。
我开始尝试使用std::function来实现这一点,但遇到了一些问题,然后决定仅使用原始MFPs重试。(我仍然愿意考虑使用std::function,并且我将接受一个向下面展示如何使用该方法实现我的确切需求的答案。但我仍然想知道我的当前方法有什么问题。)
我能够让这个方法在单个类中工作。但是我实际上希望委托映射由抽象基类提供,然后派生类将其委托注册到该映射中。除非我在下面的代码中犯了一些错误,否则这似乎是不可能的;似乎成员函数指针不能是多态的。
我得到的编译错误如下:
mfp5.cpp: In constructor ‘Derived::Derived()’:
mfp5.cpp:41:21: error: cannot convert ‘int (Derived::*)(const Base::EventContext&)’ to ‘std::map<std::basic_string<char>, int (Base::*)(const Base::EventContext&)>::mapped_type {aka int (Base::*)(const Base::EventContext&)}’ in assignment
_delegates["foo"] = &Derived::FooEventHandler;
问题
- 下面的代码中我犯了错误吗?还是这真的不允许?简而言之,我有一个
Base::*
的std :: map,并且我想将一些Derived::*
插入其中。 - 是否有其他推荐的方法来实现这个目标?
代码
class Base
{
public:
struct EventContext
{
int data1;
};
Base() {}
virtual int ProcessEvent(std::string event, EventContext ctx) =0;
protected:
typedef int (Base::* EventHandler)(const EventContext& context);
typedef std::map<std::string, EventHandler> EventDelegateMap;
EventDelegateMap _delegates;
};
.
class Derived: Base
{
public:
Derived();
int ProcessEvent(std::string event, EventContext ctx);
private:
int FooEventHandler(const EventContext& context);
int BarEventHandler(const EventContext& context);
int QuxEventHandler(const EventContext& context);
};
Derived::Derived() :Base()
{
_delegates["foo"] = &Derived::FooEventHandler; // error
_delegates["bar"] = &Derived::BarEventHandler; // error
_delegates["qux"] = &Derived::QuxEventHandler; // error
}
std::function
的解决方案是什么样子的。使用std::function
可以使整个系统更加通用(如果需要,可以使用 lambda 表达式或非成员函数,或者想出一个不需要继承的系统)。 - Some programmer dudetypedef int (Base::*EventHandler)(const EventContext& context); typedef std::function EventDelegate;
typedef std::map EventDelegateMap;
但是我被一些晦涩难懂的编译器错误所困扰。(C++模板的可读性最差的部分就是编译器警告和错误。) - Cognitive Hazard