2010-01-31 4 views
49

Ich frage mich, was der Unterschied zwischen der Verwendung einer statischen Const und eine Enum-Hack bei der Verwendung von Vorlagen Metaprogrammierung Techniken ist.Template Metaprogramming - Unterschied zwischen der Verwendung von Enum Hack und statische Const

EX: (Fibonacci über 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; 
}; 

gegen

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

Warum übereinander verwenden? Ich habe gelesen, dass der Enum-Hack verwendet wurde, bevor statische Const in Klassen unterstützt wurde, aber warum jetzt verwenden?

+0

+1: eine große Frage in der Tat, und ich würde auch gerne sehen, was die Antworten sein werden, außer für die offensichtlichen. –

+2

statische const erlaubt andere Typen als int. zum Beispiel doppelt. –

Antwort

34

Aufzählungen sind nicht lvals, statische Elementwerte sind und als Referenz übergeben, wenn die Vorlage instanziiert werden:

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

Wenn Sie reine Kompilierung Berechnungen tun wollen etc. Dies ist ein unerwünschter Nebeneffekt .

Der wichtigste historische Unterschied ist, dass Enums auch für Compiler funktionieren, bei denen die In-Klassen-Initialisierung von Member-Werten nicht unterstützt wird. Dies sollte jetzt in den meisten Compilern behoben sein.
Es kann auch Unterschiede in der Kompilierungsgeschwindigkeit zwischen Enum- und statischen Konflikten geben.

Es gibt einige Details in den boost coding guidelines und older thread in den Boost-Archiven zum Thema.

12

Für einige der ehemalige scheint weniger von einem Hack, und natürlicher. Wenn Sie die Klasse verwenden, hat sie auch Speicher zugewiesen, so können Sie zum Beispiel die Adresse von val nehmen.

Letzteres wird von einigen älteren Compilern besser unterstützt.

+0

Danke. Genau die Art von Antwort, die ich suchte. – Anonymous

+1

Persönlich stimme ich überhaupt nicht zu. Dann erscheint Enum-Version natürlicher. Warum braucht man eine physikalische Größe? Enum ist die Darstellung eines konstanten Wertes. Die Verwendung eines statischen const int scheint eher so zu sein, als würde man einen Schritt zurück zu der Zeit machen, in der wir Makros verwenden mussten, um konstante Werte darzustellen. –

+2

@Martin, was hat die Schlüsselwortaufzählung mit Berechnung zu tun? Aber Punkt genommen - jeder kann seinen eigenen Punkt darauf haben. –

1

Auf der anderen Seite auf @Georg ‚s Antwort, wenn eine Struktur, die eine statische const Variable enthält in einer speziellen Vorlage definiert ist, muss es in der Quelle erklärt werden, damit der Linker es finden kann und ihm tatsächlich eine Adresse geben referenziert werden von. Dies kann unnötigerweise (abhängig von den gewünschten Effekten) zu unelegantem Code führen, insbesondere wenn Sie versuchen, eine Header-Only-Library zu erstellen. Sie könnten es lösen, indem Sie die Werte in Funktionen umwandeln, die den Wert zurückgeben, was die Vorlagen auch für Laufzeit-Informationen öffnen könnte.

Verwandte Themen