我有一个基类和一个类,应该是仿函数,像这样:
class BFunctor {};
class Add : public BFunctor {
public:
int operator()(int x, int y) {
return x + y;
}
};
我打算创建几个这些子类,并将指向它们的指针存储在称为ops的映射中,如下所示:
map<string, BFunctor*> ops {};
Add add;
ops["sum"] = &add;
但是,这样做之后,为什么不能这样使用函数对象:
int x = ops["sum"](3, 5);
我的linter表示“明显调用的括号前的表达式必须具有(指针到)函数类型”
编译器说“错误:表达式不能用作函数”。
答案 0 :(得分:7)
如评论中所述,您需要在BFunctor
中定义要使用的成员,在这种情况下为operator()
class BFunctor {
virtual int operator()(int x, int y) = 0;
};
class Add : public BFunctor {
public:
int operator()(int x, int y) override {
return x + y;
}
};
您还需要取消引用存储在地图中的指针,因为指针 也没有operator()
。
std::map<string, BFunctor*> ops {};
Add add;
ops["sum"] = &add;
int x = (*ops["sum"])(3, 5);
但是您不必自己执行此操作。 already exists在standard library
中#include <functional>
using BFunctor = std::function<int(int, int)>;
using Add = std::plus<int>;
int main() {
std::map<string, BFunctor> ops {};
Add add;
ops["sum"] = add;
int x = ops["sum"](3, 5);
}
答案 1 :(得分:5)
有几个问题。
正如注释中已经提到的,基类中没有operator()
,因此,如果要通过指向它的指针进行调用,则必须提供一个(可能没有实现)并使其virtual
,因此它可以分派到正确的派生类。
第二,您有一个指向类的指针,因此不能像通过函数指向指针那样通过它进行调用-您必须先取消引用它:
(*ops["sum"])(3, 5);
或者,如果需要:
ops["sum"]->operator()(3,5);
完整示例here。