3

どのタイプのオブジェクトを割り当てる必要があるかを実行時に決定する方法を探しています( type の特定のクラス名に基づいてconst char*)。

もちろん、最も簡単な方法はifs / else ifsの負荷を使用することですが、100を超える異なるクラスがあり(少なくともそれらはすべて1つの基本クラスから派生しています)、新しいクラスをかなり定期的に追加する必要があるため、適用できないようです同じように。

私はすでに最初のドラフトを思いつきましたが、残念ながらまだコンパイルされていません (mingw & g++ 4.4)

template<typename TBase, typename TDerived, typename... TArgs>
Base* get_classobject(const char* classname)
{
    if(strcmp(classname,typeid(TDerived).name())==0)
        return new TDerived; //
    else if(sizeof...(TArgs)>0)
        return get_classobject<TBase,TArgs...>(classname);
    else
        return 0;
}


int main()
{
    Base* obj = get_classobject<Base,A,Foo,B,C>("Foo");
    // ^- Types A B C and Foo are all derived from Base
    delete obj; //of course we got an virtual dtor ;)
    return 0;
}

しかし、それsizeof...(TArgs)>0はgccget_classobject<TBase,const char*>(const char*)が失敗するコードを生成しようとするのを止めません

これを修正する方法、または他のアイデアはありますか?ありがとう。

編集:私はそれを解決しました:

template<typename TBase, typename TDerived>
Base* get_classobject(const char* classname)
{
    if(strcmp(classname,typeid(TDerived).name())==0)
        return new TDerived;
    return 0;
}

template<typename TBase, typename TDerived, typename TArg, typename... TArgs>
Base* get_classobject(const char* classname)
{
    if(strcmp(classname,typeid(TDerived).name())==0)
        return new TDerived;
    return get_classobject<TBase,TArg,TArgs...>(classname);
}

編集 興味のある読者へ:
上記の実装はコンパイラにまったく依存していないことに注意してください。の出力は、typeif(sometype).name()コンパイラ/実装固有です。すべての派生クラス内で変数または関数を使用するstatic const char* nameと、これは修正されますが、多くの作業が追加されます (もちろん、これにはマクロを使用できますが、既にマクロを使用している場合は、別のオブジェクト ファクトリ メソッドを使用することもできます)。

4

4 に答える 4

3

宣言していただけないでしょうか

template<typename TBase, typename TDerived, typename TArg, typename... TArgs>

?

次に、次の場合に特化できます

typename TBase, typename TDerived, typename TArg
于 2010-01-15T22:32:17.680 に答える
2

hereの回答を読んでください。おそらく工場が必要です。

于 2010-01-15T22:36:02.773 に答える
1

可変個引数のテンプレートを持たない特殊な get_classobject() を作成するのはどうですか? それは再帰を止めるでしょう。

次に、可変個引数テンプレートを使用した 1 つの定義と、単にtemplate<typename TBase, typename TDerived>. もう 1 つのアイデアは、const char* のみを受け入れて 0 を返す非テンプレート オーバーロードを作成することです。

于 2010-01-15T22:37:33.707 に答える
0

これは、古典的なオブジェクト ファクトリ パターンを探しているように思えます。このstackoverflowの質問を見てください。個人的にはこの方法が好きです

于 2010-01-15T22:36:04.817 に答える