2009-11-14 19 views
6

C'è un modo per scegliere il tipo generico di una classe in fase di esecuzione o si tratta di una cosa in fase di compilazione in C++?È possibile scegliere un parametro di tipo generico C++ in fase di runtime?

Quello che voglio fare è qualcosa di simile a questo (pseudocodice):

Generictype type; 
if(somveval==1) 
    type = Integer; 
if(someval==2) 
    type = String; 

list<type> myList; 

Questo è possibile in C++? e se si, come?

+2

Tutto è possibile. Ma quello che stai cercando di fare non è facile in C++. Se spieghi perché stai provando a farlo forse potremmo darti un consiglio migliore. –

risposta

10

È una cosa a tempo di compilazione. I tipi di parametri del modello devono essere noti al compilatore in fase di compilazione.

Detto questo, utilizzando determinate tecniche di meta-programmazione del modello, è possibile scegliere un tipo o un altro tempo di compilazione AT, ma solo se tutti i tipi possibili sono noti in fase di compilazione e solo se la condizione per selezionare un il tipo può essere risolto al momento della compilazione.

Ad esempio, utilizzando la specializzazione parziale è possibile selezionare un tipo in fase di compilazione sulla base di un numero intero:

template <typename T> 
class Foo 
{ }; 

template <int N> 
struct select_type; 

template<> 
struct select_type<1> 
{ 
    typedef int type; 
}; 

template<> 
struct select_type<2> 
{ 
    typedef float type; 
}; 

int main() 
{ 
    Foo<select_type<1>::type> f1; // will give you Foo<int> 
    Foo<select_type<2>::type> f2; // will give you Foo<float> 
} 
0

non riesco a pensare a una situazione in cui questo sarebbe utile, ma & hellip;

#include "boost/variant.hpp" 
#include <list> 
#include <string> 

boost::variant<std::list<int>, std::list<std::string> > 
unknown(int someval) { 
    if (someval == 1) 
     return boost::variant<std::list<int>, std::list<std::string> >(
       std::list<int>()); 
    else if (someval == 2) 
     return boost::variant<std::list<int>, std::list<std::string> >(
       std::list<std::string>()); 
} 
1

Come altri hanno anche risposto, la risposta alla tua domanda è "no", C++ non supporta la tipizzazione dinamica in fase di esecuzione. Volevo solo far notare che, a seconda di ciò che stai cercando di ottenere, puoi simulare questa digitazione dinamica utilizzando un unione, che è il modo in cui lo VARIANT type è implementato in COM.

0

il più vicino si ottiene è:

template <typename T> 
void do_stuff_with_list 
{ 
    list<T> myList; 
    ... 
} 

enum Type 
{ 
    Integer = 1, 
    String 
}; 

void do_stuff(Type type) 
{ 
    switch (type) 
    { 
    case Integer: 
     do_stuff_with_list<int>(); 
     break; 
    case String: 
     do_stuff_with_list<string>(); 
     break; 
    }; 
} 
2

E 'possibile con Boost.Variant (numero fisso di diversi tipi) o Boost.Any (un tipo in grado di memorizzare qualsiasi tipo, in pratica il tuo "vuoto puntatore "ma con informazioni sul tipo).

È anche possibile che String e Integer siano derivati ​​da una classe di base polimorfica. (Ma per quello dovrebbero implementare la stessa interfaccia, che potrebbe essere o non essere possibile nel tuo caso.)

Generalmente, il polimorfismo è il modo più semplice per farlo, e questo è effettivamente usato tutto il tempo.

Variant e Qualsiasi richiedono un bel po 'di lavoro da utilizzare: è ancora necessario in qualche modo ottenere il contenuto come il tipo giusto che stanno memorizzando. (Assomiglia a come se si dovessero utilizzare i down-cast per le classi derivate, invece di affidarsi a chiamate di metodo polimorfiche.)

Problemi correlati