In linea di principio, questo è possibile, anche se la soluzione probabilmente non è quello che stai cercando.
In breve, è necessario fornire una mappatura esplicita dai tipi ai valori interi, con una voce per ogni tipo possibile:
template< typename T >
struct type2int
{
// enum { result = 0 }; // do this if you want a fallback value
};
template<> struct type2int<AClass> { enum { result = 1 }; };
template<> struct type2int<BClass> { enum { result = 2 }; };
template<> struct type2int<CClass> { enum { result = 3 }; };
const int i = type2int<T>::result;
Se non si fornisce l'implementazione di ripiego nel modello di base , questo fallirà per tipi sconosciuti se T
, altrimenti restituirebbe il valore di fallback.
A seconda del contesto, potrebbero esserci anche altre possibilità. Ad esempio, è possibile definire quei numeri all'interno entro i tipi stessi:
class AClass {
public:
enum { inta_val = 1 };
// ...
};
class BClass {
public:
enum { inta_val = 2 };
// ...
};
// ...
template< typename T >
struct type2int
{
enum { result = T::int_val }; // will fail for types without int_val
};
Se si dà più contesto, ci potrebbero essere altre soluzioni, anche.
Edit:
In realtà non c'è più contesto ad esso. Stavo esaminando se fosse effettivamente possibile, ma senza assegnare i numeri stessi.
penso che l'idea di Mike di ordinamento è un buon modo per fare questo (ancora una volta, per un insieme fisso di tipi) senza dover assegnare esplicitamente i numeri: sono implicitamente dato dal l'ordinamento. Tuttavia, penso che questo sarebbe più facile utilizzando una lista di tipi. L'indice di qualsiasi tipo nell'elenco sarebbe il suo numero. Penso che qualcosa di simile al seguente potrebbe fare:
// basic type list manipulation stuff
template< typename T1, typename T2, typename T3...>
struct type_list;
// meta function, List is assumed to be some instance of type_list
template< typename T, class List >
struct index_of {
enum { result = /* find index of T in List */ };
};
// the list of types you support
typedef type_list<AClass, BClass, CClass> the_type_list;
// your meta function
template< typename T >
struct type2int
{
enum { result = index_of<T, the_type_list>::result };
};
Si desidera anche supportare tipi come 'void (*) (AClass const (*) [4])'? Penso che sia ancora possibile trattare un tipo come un albero in cui i tipi fondamentali e i tipi definiti dall'utente sono le foglie. – sellibitze
L'esempio non richiede che ':: value' sia una costante di tempo di compilazione. È un requisito? –
Penso che tecnicamente, questo è impossibile da realizzare, anche se per tipi arbitrari: ci sono molti più tipi di quanti ce ne siano possibili. Ricorda ogni tipo di 'struct A; struct B; B [1]; B [2]; 'etc sono diversi. Come potrebbe mai funzionare? –