2012-01-31 9 views
15

może ktoś wyjaśnić, dlaczego kompilator przyjmuje tylko ten kodszablon przeciążenia i SFINAE działa tylko z funkcji, ale nie klas

template<typename L, size_t offset, typename enable_if< (offset<sizeof(L)), int >::type =0> 
void a_function(){} 

template<typename L, size_t offset, typename enable_if< (offset==sizeof(L)), int >::type =0> 
void a_function(){} 

ale nie w ten sposób:

template<typename L, size_t offset, typename enable_if< (offset<sizeof(L)), int >::type =0> 
class a_class{}; 

template<typename L, size_t offset, typename enable_if< (offset==sizeof(L)), int >::type =0> 
class a_class{}; 

kompilator widzi drugiej klasy szablon jako redefinicja pierwszego.

+2

Oh, że '<' 'sizeof' przed sprawia, że ​​mój mózg boli^_^ –

Odpowiedz

12

Musisz użyć specjalizacji dla klas. Zazwyczaj to jest zrobione z dodatkowym parametrem:

template <class P, class dummy = void> 
class T; 

template <class P> 
class T<P, typename enable_if<something, void>::type> { 
    the real thing 
}; 

Dwa klasa (lub klasy szablonu) deklaracji o takiej samej nazwie należy zawsze zadeklarować tę samą klasę lub klasy szablonu (lub być specjalizacji, w tym przypadku jest to nadal ten sam szablon).

+0

' nazwa_pliku enable_if :: type = 0' jest równoważne 'int __anonymous_param = 0', gdy" coś "jest prawdziwe. – kennytm

+0

Ale dlaczego udało się to funkcji? –

+2

@LightnessRacesinOrbit, ponieważ możesz przeciążyć funkcje, ale nie typy. W wersji funkcji definiujesz dwa potencjalne przeciążenia (dla różnych zestawów typów), podczas gdy w drugim przypadku definiujesz dwa szablony o tej samej nazwie, które nie mogą być wykonane. Dwie funkcje z jedną nazwą dobrze (o ile nie są niejednoznaczne), dwa typy o tej samej nazwie, niezbyt dobre, nawet jeśli faktycznie są szablonami typu. –

1

Prawdopodobnie chcesz zrobić coś takiego (ideone.com link):

#include <iostream> 

template< typename PL, size_t pOffset, int pC = int(sizeof(PL)) - int(pOffset) >= 0 ? (int(sizeof(PL)) - int(pOffset) == 0 ? 0 : 1) : -1 > 
class TClass 
{ 
}; 

template< typename PL, size_t pOffset > 
class TClass< PL, pOffset, -1 > 
{ 
public: 
    static int const sI = -1; 
}; 

template< typename PL, size_t pOffset > 
class TClass< PL, pOffset, 0 > 
{ 
public: 
    static int const sI = 0; 
}; 

template< typename PL, size_t pOffset > 
class TClass< PL, pOffset, 1 > 
{ 
public: 
    static int const sI = 1; 
}; 

int main(void) 
{ 
TClass< char, 0 > lC0; 
TClass< char, 1 > lC1; 
TClass< char, 2 > lC2; 

std::cout << lC0.sI << " : " << lC1.sI << " : " << lC2.sI << std::endl; 

return (0); 
} 

wyjście Program:

1 : 0 : -1 
Powiązane problemy