Domanda

Sto cercando un modo per determinare in fase di esecuzione, quale tipo di oggetto deve essere alloced (basata su un determinato nome di classe, che è di tipo const char*).

Bene il modo più semplice, naturalmente, è quello di utilizzare i carichi di ifs / else ifs, ma quello non sembra applicabile, perché ho> 100 classi diverse (bene almeno derivano tutte da una classe di base), e devo aggiungere nuovi classi abbastanza regolarmente pure.

I già si avvicinò con una prima bozza, ma purtroppo doesnt compilo ancora (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;
}

, ma che pretende molto sizeof...(TArgs)>0 fermata gcc dal tentativo di generare il codice per get_classobject<TBase,const char*>(const char*) che non riesce

Avete qualche idea, come riparare questo, o qualsiasi altra idea? Grazie.

EDIT: ho risolto:

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

EDIT Per i lettori interessati:
Si dovrebbe ora che l'attuazione di cui sopra non è compilatore indipendente a tutti. L'uscita di typeif(sometype).name() è compilatore / implementazione specifica. Utilizzando una variabile static const char* name o funzione all'interno di tutte le classi derivate, sarebbe risolvere questo problema, ma aggiunge un po 'di lavoro (naturalmente è possibile utilizzare una macro per questo, ma se si utilizza già le macro, si potrebbe partecipavano utilizzare un altro metodo oggetto di fabbrica)

È stato utile?

Soluzione

Non si può semplicemente dichiarare

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

Quindi è possibile specializzarsi per il caso di

typename TBase, typename TDerived, typename TArg

Altri suggerimenti

Leggi le risposte oltre qui , probabilmente bisogno di una fabbrica.

Che ne dite di fare un get_classobject specializzata () senza temlates variadic? Che sarebbe fermare la ricorsione.

Si potrebbe quindi avere una definizione con la mascherina variadic, e un altro di appena template<typename TBase, typename TDerived>. Un'altra idea è quella di fare un sovraccarico di non-modello che accetta solo const char *, e restituisce 0.

Questo suona come si sta cercando per il modello oggetto factory classica. Date un'occhiata a questo StackOverflow domanda . Personalmente mi piace questo metodo

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top