2012-03-01 19 views
13

Próbowałem uzyskać specjalizację opartą na wartości całkowitej jako typ szablonu. Jeśli używam jednej liczby całkowitej, specjalizacja jest prosta. Czy możliwe jest posiadanie prostej specjalizacji szablonów w oparciu o zasięg bez użycia podstawienia doładowania.Specjalizacja szablonów opartych na zasięgu całkowitym

Jest to kod przedstawiciel przekłada się

template <typename int val> 
class Param 
{ 
public: 

}; 

template <> class Param<0 to 100> 
{ 

}; 

template <> class Param<100 to 175> 
{ 

}; 

Odpowiedz

13

Oto jeden (prosty) sposób, aby realizować swoje wymagania przy zastosowaniu SFINAE:

template<bool> struct Range; 

template<int val, typename = Range<true> > 
class Param 
{}; 

template<int val> 
class Param<val, Range<(0 <= val && val <= 100)> > 
{}; 

template<int val> 
class Param<val, Range<(100 < val && val <= 175)> > 
{}; 

Demo.

+0

Jeszcze lepiej. Wielkie dzięki! – Ram

+0

Ah cool. Choć tak naprawdę jedyną różnicą jest to, że musisz napisać '(x

+1

To dobrze, że to pytanie ma teraz dwa sposoby, aby zrobić to dla przyszłych użytkowników. + 1 przy okazji. –

-3

Czy to możliwe, aby mieć prosty szablon specjalizacji w oparciu o zakres bez użycia podbicia fundamentów.

Nie dla C++ 03 w naprawdę elegancki, zwięzły, łatwy w utrzymaniu i ogólny sposób, w którym można łatwo określić arbiterily duże zakresy. Aby zachować zwięzłość kodu, potrzebujesz czegoś takiego jak biblioteka preprocesora doładowania, aby zapętlić zakres wartości.

Sans BOOST lub reimplementacja ogromnych jego części, można utworzyć trochę smutnych małych makr, aby wywołać początkowe makro dla określonej liczby kolejnych wartości. Na przykład:

#define X(N) template <> class Param<N> { ... }; 
#define X2(N) X(N) X(N+1) 
#define X4(N) X2(N) X2(N+2) 
#define X8(N) X4(N) X4(N+4) 
... 

// template <> class Param<100 to 175> then becomes 
X64(100); // 100..163 
X8(164); // 164..171 
X4(172); // 172..175 

Alternatywnie, można użyć programu/skryptu do pisania kodu C++, jak we wcześniejszym etapie kompilacji, że czasami działa się lepiej - raz gorzej - niż preprocesora hackery.

13

Można użyć SFINAE z std::enable_if zrobić własny poręczny kompilacji klasy badania zakres:

#include <iostream> 
#include <type_traits> 

using namespace std; 

template<int Start, int End, int Val, class Enable = void> 
struct crange { }; 

template<int Start, int End, int Val> 
struct crange<Start, End, Val, typename std::enable_if<Val >= Start && Val <= End>::type> { 
    typedef void enabled; 
}; 

template<int Val, class Enable = void> 
class Param { 
public: 
    Param() : value(422) { } 

    int value; 
}; 

template<int Val>    // V VV the range [x, y] 
class Param<Val, typename crange<0, 10, Val>::enabled> { 
public: 
    Param() : value(1.32) { } 

    double value; 
}; 

int main() { 
    Param<1> pdouble; 
    Param<50> pint; 

    cout << pdouble.value << endl; // prints 1.32 
    cout << pint.value << endl; // prints 422 
} 
+1

Seth, Wielkie dzięki. Jeśli był jakiś sposób, aby oznaczyć twoją odpowiedź jako użyteczną wiele razy, to klikałbym ten przycisk sto razy! – Ram

+2

+1 za dobrą odpowiedź, ale jest o wiele bardziej złożona niż potrzeba. Zobacz moją odpowiedź. – iammilind

Powiązane problemy