如何调用存储在地图中的仿函数?

Ber*_*USA 2 c++

我有一个基类和一个类,应该是仿函数,像这样:

class BFunctor {};

class Add : public BFunctor {
public:
    int operator()(int x, int y) {
        return x + y;
    }
};
Run Code Online (Sandbox Code Playgroud)

我打算创建几个这些子类,并在名为ops的映射中存储指向它们的指针,如下所示:

map<string, BFunctor*> ops {};
Add add;
ops["sum"] = &add;
Run Code Online (Sandbox Code Playgroud)

但是,在这之后,为什么我不能像这样使用函数对象:

int x = ops["sum"](3, 5);
Run Code Online (Sandbox Code Playgroud)

我的linter说"明显调用的括号前面的表达式必须有(指向 - ) - 函数类型"

并且编译器说"错误:表达式不能用作函数".

Cal*_*eth 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;
    }
};
Run Code Online (Sandbox Code Playgroud)

您还需要取消引用存储在地图中的指针,因为指针没有operator().

std::map<string, BFunctor*> ops {};
Add add;
ops["sum"] = &add;

int x = (*ops["sum"])(3, 5);
Run Code Online (Sandbox Code Playgroud)

但是你自己不需要这样做.它已存在标准库中

#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);
}
Run Code Online (Sandbox Code Playgroud)


jro*_*rok 5

有几个问题.

正如在注释中已经提到的operator()那样,基类中没有,所以如果你想通过指向它的指针调用,你必须提供一个(可能没有实现)并且也可以创建它virtual,所以它可以调度到正确的派生类.

其次,你有一个指向类的指针,所以你不能像通过指针到函数那样调用它 - 你必须首先取消引用它:

(*ops["sum"])(3, 5);
Run Code Online (Sandbox Code Playgroud)

或者,如果你想:

ops["sum"]->operator()(3,5);
Run Code Online (Sandbox Code Playgroud)

完整的例子在这里.