2011-04-21 6 views
6

Zastanawiam się, czy istnieje jakikolwiek sposób ograniczenia kodu generującego szablon przy użyciu niestandardowych warunków w moim przypadku chcę, aby funkcja foo była wywoływana tylko wtedy, gdy klasa klasy T ma dziedziczone przez pasek klasy (coś takiego)Ograniczenie klasy szablonów

template <class T:public bar> void foo() 
{ 
    // do something 
} 
+3

Możesz być w stanie używać doładowania 'enable_if'. –

+0

Jeśli masz do czynienia z publicznym dziedzictwem, to jest jeszcze jeden sposób. Zobacz moją odpowiedź. – iammilind

Odpowiedz

9

można ograniczyć T chociaż używając "Failure Zmiana Czy nie jest to błąd" (SFINAE):

template <typename T> 
typename std::enable_if<std::is_base_of<bar, T>::value>::type foo() 
{ 

} 

Jeśli T nie pochodzi od bar, specjalizację szablonu funkcji zawiedzie i nie będzie brane pod uwagę podczas rozwiązywania przeciążenia. std::enable_if i std::is_base_of to nowe składniki standardowej biblioteki C++ dodane w nadchodzącej wersji, C++ 0x. Jeśli implementacja kompilatora/biblioteki standardowej jeszcze ich nie obsługuje, możesz je również znaleźć w C++ TR1 lub Boost.TypeTraits.

+0

Rzeczywiście, albo jeśli twoja biblioteka 'std' nie ma' is_base_of', to jest w Boost. –

+0

Tak. Równoważnik Boost byłby: 'boost :: enable_if > :: type'; 'std :: enable_if' przyjmuje jako pierwszy argument' bool', podczas gdy 'boost :: enable_if' przyjmuje typ. 'std :: enable_if' jest równoważne' boost :: enable_if_c'. –

+0

Czy masz pojęcie, w jaki sposób sama biblioteka STD zaimplementowała enable_if lub is_base_of classes? – Ali1S232

0

Tak, można zastosować następującą technikę (w przypadku dziedziczenia publicznego). Spowoduje to narzut tylko jednej inicjalizacji wskaźnika.

Edit: Re pisania

template<typename Parent, typename Child> 
struct IsParentChild 
{ 
    static Parent* Check (Child *p) { return p; } 
    Parent* (*t_)(Child*); 
    IsParentChild() : t_(&Check) {} // function instantiation only 
}; 

template<typename T> 
void foo() 
{ 
    IsParentChild<Bar, T> check; 
// ... 
} 
Powiązane problemy