2012-02-01 15 views
8

Ho qualcosa di simile:let template scegliere tra char/short/int specificando bitsize?

template<int SIZE> 
struct bin { 
private: 
public: 
    struct { 
     int _value : SIZE; 
    }; 
} 

E 'possibile cambiare il tipo di dati _value a seconda delle dimensioni? Se SIZE è < = 7, voglio _value essere un carattere. Se è> = 8 e < = 15, voglio che sia breve e se è < = 31, voglio che sia un numero intero.

risposta

10

Questo non è particolarmente elegante, ma:

template <unsigned int N> 
struct best_integer_type { 
    typedef best_integer_type<N-1>::type type; 
}; 

template <> 
struct best_integer_type<0> { 
    typedef char type; 
}; 

template <> 
struct best_integer_type<8> { 
    typedef short type; 
}; 

template <> 
struct best_integer_type<16> { 
    typedef int type; 
}; 

template <> 
struct best_integer_type<32> { 
    // leave out "type" entirely, to provoke errors 
}; 

Poi nella classe:

typename best_integer_type<SIZE>::type _value; 

Non si tratta con i numeri negativi per SIZE. Nemmeno il tuo codice originale, ma la tua descrizione del testo dice di usare char se SIZE <= 7. Mi aspetto che lo farà 0 <= SIZE <= 7.

+0

grazie, è esattamente quello che stavo cercando. funziona meglio di quanto mi aspettassi. – Markus

+0

Ad un certo punto potresti preoccuparti della velocità di compilazione. –

+0

@ edA-qa mort-ora-y: utilizzo della memoria di compilazione e le implementazioni generalmente impongono una "profondità di ricorsione" massima fissa per l'istanziazione del modello. Se scriviamo 'bin b;' probabilmente succederà qualcosa di spiacevole. Ma supponendo che usiamo solo numeri ragionevoli, il compilatore dovrà sempre creare al massimo 31 tipi (per TU), il che IMO è improbabile che sia mai un peso significativo se non in un esempio forzato. Mi aspetto che ci siano modelli standard che impongono un sovraccarico di un paio di ordini di grandezza peggiore. –

8

Boost.Integer ha utilities for type selection:

boost::int_t<N>::least
Il, built-in, firmato tipo integrale più piccolo con almeno N bit, tra cui il bit del segno. Il parametro dovrebbe essere un numero positivo. Un errore in fase di compilazione risulta se il parametro è maggiore del numero di bit nel tipo di intero più grande.

boost::int_t<N>::fast
Il più facile da manipolare, built-in, firmato tipo integrale con almeno N bit, compreso il bit di segno. Il parametro dovrebbe essere un numero positivo. Un errore in fase di compilazione risulta se il parametro è maggiore del numero di bit nel tipo di intero più grande.

+1

Avrei dovuto sapere che 'boost' aveva ... –

+1

@Matthieu: Manca solo Boost.Coffee? :) –