将函数指针插入到具有多态返回类型的映射中

Insert function pointer into map with polymorphic return type

本文关键字:返回类型 多态 映射 函数 指针 插入      更新时间:2023-10-16

我不知道如何为这个问题命名。我有一个基类和两个继承类:

class Base {};
class Action : public Base {};
class Title : public Base {};

现在假设我有两个返回 Action *Title * 的函数:

Action *getAction() { return new Action; }
Title *getTitle() { return new Title; }

有没有办法把这两个函数放到地图里?这样:

int main()
{
    std::map<std::string, Base *(*)()> myMap;
    myMap["action"] = getAction;
    myMap["title"] = getTitle;
    return 0;
}

现在我收到一个错误:

invalid conversion from `Action* (*)()' to `Base* (*)()'

我可以更改函数的签名以始终返回基类,然后它就可以工作,但我想知道是否有另一种方法可以解决这个问题。

如果您使用:

Base *getAction() { return static_cast<Base *>(new Action); }
Base *getTitle() { return static_cast<Base *>(new Title); }

那么你不会得到这个错误。

std::function 是由 STL 提供的多态函数指针包装器。

当然,使用模板,您可以编写自己的函数包装器来存储目标、传递前向参数并进行转换。不过,这已经完成了,在决定自己推出之前,您应该认真考虑。除非您喜欢重新发明轮子或有非常特殊的要求。

作为概念证明,我有以下代码:

#include <iostream>
#include <map>
#include <functional>
struct A
{
    virtual void f() = 0;
};
struct B : public A
{
    void f() { std::cout << "B::fn"; }
};
struct C : public A
{
    void f() { std::cout << "C::fn"; }
};
B* getB() { return new B; }
C* getC() { return new C; }
int main()
{
    std::map<std::string, std::function<A*()>> m;
    m["b"] = getB;
    m["c"] = getC;
    m["b"]()->f();
    m["c"]()->f();
}

它泄漏内存,但它有效。