2010-01-31 19 views
49

Zastanawiam się, jaka jest różnica między używaniem statycznej stałej i wyłudzającym hack przy użyciu metaprogramowania szablonów.Szablon Metaprogramming - Różnica między używaniem Enuma Hack a statycznym Const

EX: (Fibonacciego przez 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 }; 
}; 

Dlaczego używać jednego nad drugim? Czytałem, że hack wyłudzeniowy był używany przed statycznym const był obsługiwany w klasach, ale dlaczego teraz go używać?

+0

+1: naprawdę ważne pytanie, a ja chciałbym zobaczyć, jakie będą odpowiedzi, z wyjątkiem oczywistych. –

+2

static const pozwala na typy inne niż int. podwójne na przykład. –

Odpowiedz

34

wyliczenia nie są lvals statyczne wartości członkowskie są i jeśli przekazywane przez referencję szablon zostanie instanciated:

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

Jeśli chcesz zrobić obliczenia czasu czystego kompilacji itd. Jest to niepożądany efekt uboczny .

Główna różnica historyczna polega na tym, że enums działa również w przypadku kompilatorów, w których inicjowanie w klasie wartości elementów nie jest obsługiwane, teraz należy to naprawić w większości kompilatorów.
Mogą występować różnice w szybkości kompilacji między wartościami wyliczonymi i statycznymi.

Istnieją pewne szczegóły w boost coding guidelines i older thread w archiwach wspomagających dotyczących tematu.

12

Dla niektórych ten pierwszy może wydawać się mniej hackowy i bardziej naturalny. Ma również pamięć przeznaczoną dla siebie, jeśli używasz klasy, dzięki czemu możesz na przykład wziąć adres val.

Ten drugi jest lepiej obsługiwany przez niektóre starsze kompilatory.

+0

Dzięki. Dokładnie taki rodzaj odpowiedzi, którego szukałem. – Anonymous

+1

Osobiście całkowicie się nie zgadzam. Wtedy wersja enum wydaje się bardziej naturalna. Dlaczego potrzebna jest zmienna fizyczna? Enum jest reprezentacją wartości stałej. Używanie statycznego const int wydaje się raczej robić krok wstecz do czasu, w którym musieliśmy używać makr do reprezentowania stałych wartości. –

+2

@Martin, co wyliczenie słowa kluczowego robi z obliczeniem? Ale punkt zaczepiony - każdy może mieć na to swój punkt widzenia. –

1

Po drugiej stronie do odpowiedzi @Georg, gdy struktura zawierająca statyczną zmienną stałą jest zdefiniowana w wyspecjalizowanym szablonie, musi być zadeklarowana w źródle, aby linker mógł ją znaleźć i faktycznie podać jej adres należy się do niego odwoływać. Może to niepotrzebnie (w zależności od pożądanych efektów) powodować nieelegancki kod, szczególnie jeśli próbujesz utworzyć bibliotekę tylko nagłówkową. Można go rozwiązać, konwertując wartości na funkcje, które zwracają wartość, co może otworzyć szablony również na informacje o czasie pracy.

Powiązane problemy