どのタイプのオブジェクトを割り当てる必要があるかを実行時に決定する方法を探しています( type の特定のクラス名に基づいてconst char*
)。
もちろん、最も簡単な方法はif
s / else if
sの負荷を使用することですが、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
と、これは修正されますが、多くの作業が追加されます (もちろん、これにはマクロを使用できますが、既にマクロを使用している場合は、別のオブジェクト ファクトリ メソッドを使用することもできます)。