1

この質問にタイトルを付ける方法が正確にわかりませんでした。基本クラスと 2 つの継承クラスがあります。

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

Action *ここで、またはのいずれかを返す 2 つの関数があるとしますTitle *

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

これら 2 つの関数をマップに入れる方法はありますか? そのようです:

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

    return 0;
}

現在、エラーが発生しています:

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

関数のシグネチャを変更して、常に基本クラスを返すようにすることもできますが、それは機能しますが、これを回避する別の方法があるかどうか疑問に思っています。

4

2 に答える 2

2

使用する場合:

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

その後、このエラーは発生しません。

std::functionSTL によって提供される多態的な関数ポインタ ラッパーです。

もちろん、テンプレートを使用して、ターゲットを格納し、前方引数を渡し、変換を行う独自の関数ラッパーを作成できます。ただし、これはすでに行われているため、自分でロールすることを決定する前に、慎重に検討する必要があります. 車輪の再発明を楽しんだり、非常に特別な要件がある場合を除きます。

于 2012-11-19T10:06:49.257 に答える
1

概念実証として、次のコードがあります。

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

メモリリークしますが、動作します。

于 2012-11-19T10:34:43.580 に答える