Вставить указатель функции в карту с полиморфным типом возврата

Я не знал точно, как озаглавить этот вопрос. У меня есть базовый класс и два наследующих класса:

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* (*)()'

Я мог бы изменить сигнатуру функций, чтобы они всегда возвращали базовый класс, и тогда это сработало бы, но мне интересно, есть ли другой способ обойти это.

1

Решение

Если вы используете:

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

тогда вы не получите эту ошибку.

std::function является оберткой для указателя на полиморфную функцию, предоставляемой STL

Конечно, используя шаблоны, вы можете написать свою собственную функцию-обертку, которая хранит цель, передает аргументы вперед и выполняет преобразование. Это уже было сделано, и вы должны серьезно подумать, прежде чем вы решите бросить свой собственный. Если вы не любите изобретать колеса или предъявляете особые требования.

2

Другие решения

В качестве доказательства концепции у меня есть этот код:

#include <iostream>
#include <map>
#include <functional>

struct A
{
virtual void f() = 0;
};

struct B : public A
{
void f() { std::cout << "B::f\n"; }
};

struct C : public A
{
void f() { std::cout << "C::f\n"; }
};

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();
}

Утечка памяти, но это работает.

1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector