2010-01-31 4 views
49

Mi chiedo quale sia la differenza tra l'uso di un const statico e un enum hack quando si usano le tecniche di metaprogrammazione del modello.Metaprogrammazione modello - Differenza tra l'uso di Enum Hack e Statatic Const

EX: (Fibonacci via TMP)

template< int n > struct TMPFib { 
    static const int val = 
    TMPFib< n-1 >::val + TMPFib< n-2 >::val; 
}; 

template<> struct TMPFib<1> { 
    static const int val = 1; 
}; 

template<> struct TMPFib<0> { 
    static const int val = 0; 
}; 

vs.

template< int n > struct TMPFib { 
    enum { 
    val = TMPFib< n-1 >::val + TMPFib< n-2 >::val 
    }; 
}; 

template<> struct TMPFib<1> { 
    enum { val = 1 }; 
}; 

template<> struct TMPFib<0> { 
    enum { val = 0 }; 
}; 

Perché utilizzare uno sopra l'altro? Ho letto che l'enum hack è stato usato prima che il const statico fosse supportato all'interno delle classi, ma perché usarlo adesso?

+0

+1: una bella domanda, e mi piacerebbe anche vedere quali saranno le risposte tranne l'ovvio. –

+2

const statico consente tipi diversi da int. doppio per esempio. –

risposta

34

Enums non sono lvals, valori dei membri statici sono e se passato per riferimento il modello sarà istanziare:

void f(const int&); 
f(TMPFib<1>::value); 

Se si vuole fare calcoli di tempo puro compilazione ecc Questo è un effetto collaterale indesiderato .

La principale differenza storica è che le enumerazioni funzionano anche per i compilatori in cui l'inizializzazione in classe dei valori dei membri non è supportata, ciò dovrebbe essere risolto nella maggior parte dei compilatori ora.
Ci possono anche essere differenze nella velocità di compilazione tra enum e statico.

Ci sono alcuni dettagli nello boost coding guidelines e uno older thread negli archivi boost relativi al soggetto.

12

Per alcuni il primo può sembrare meno di un hack e più naturale. Inoltre ha memoria allocata per se stessa se si utilizza la classe, quindi è possibile ad esempio prendere l'indirizzo di val.

Quest'ultimo è meglio supportato da alcuni compilatori precedenti.

+0

Grazie. Esattamente il tipo di risposta che stavo cercando. – Anonymous

+1

Personalmente non sono assolutamente d'accordo. Quindi la versione enum sembra più naturale. Perché c'è bisogno di una variabile fisica? Enum è la rappresentazione di un valore const. Usare un const const statico sembra più come fare un passo indietro nel tempo in cui dovevamo usare le macro per rappresentare valori costanti. –

+2

@ Martin, che cosa ha a che fare l'enumerazione delle parole chiave con il calcolo? Ma punto preso - ognuno può avere il proprio punto su questo. –

1

Dall'altro lato alla risposta di @Georg, quando una struttura che contiene una variabile const statica è definita in un modello specializzato, deve essere dichiarata nella sorgente in modo che il linker possa trovarla e dargli effettivamente un indirizzo per essere referenziato da Ciò potrebbe non essere necessario (a seconda degli effetti desiderati) causa codice inelegante, specialmente se si sta tentando di creare una libreria di sola intestazione. Potresti risolverlo convertendo i valori in funzioni che restituiscono il valore, che potrebbe aprire anche i modelli alle informazioni di runtime.