2011-08-08 17 views
16

Czy jest możliwe posiadanie wielu wersji tej samej klasy, które różnią się tylko liczbą argumentów szablonu, które biorą?Przeciążanie klas szablonów według numeru parametru szablonu

Na przykład:

template<typename T> 
class Blah { 
public: 
    void operator()(T); 
}; 

template<typename T, typename T2> 
class Blah { 
public: 
    void operator()(T, T2); 
}; 

Próbuję Model Typ funktor rzeczy, które mogą podjąć zmienną liczbę argumentów (do liczby różnych szablonów, które zostały napisane na zewnątrz).

+0

Zastanawiam się, czy można zrobić coś z typelists. – john

+0

@john, to byłby dobry pomysł, ale używam MSVC++ 2010, który nie obsługuje ich, nie wierzę. –

+0

Właściwie boost :: tuple jest prawdopodobnie bardziej dostępną wersją tego samego pomysłu. Masz ogólny szablon z jednym typem, a następnie specjalistyczną wersję z krotkami dla dwóch, trzech, czterech ... typów. – john

Odpowiedz

22

Najprostszą odpowiedzią byłoby posiadanie tylko jednego szablonu, z maksymalną liczbą, którą chcesz obsłużyć, i użycie pustego miejsca dla domyślnego typu we wszystkich oprócz pierwszego typu. Następnie można użyć częściowej specjalizacji potrzebne:

template<typename T1, typename T2=void> 
struct foo { 
    void operator()(T1, T2); 
}; 

template <typename T1> 
struct foo<T1, void> { 
    void operator()(T1); 
}; 

int main() { 
    foo<int> test1; 
    foo<int,int> test2; 
    test1(0); 
    test2(1,1); 
} 
+1

Nie sądzę, że definicja 'operator() (T, T2, T3, T4)' działałaby poprawnie, gdyby niektóre typy były 'void'. –

+0

@ Masz rację, nie ma, już próbowałem. –

+2

@ben - To nie działa w ten sposób, stąd specjalizacja częściowa, która efektywnie daje "przeciążenie" na liczbie argumentów szablonu – Flexo

14

Szablon może mieć tylko jedendefinicję bazy. Jeśli potrzebujesz zmienną liczbę argumentów, a nie chcesz korzystać z „null” typu konstrukcje jak sugeruje @awoodland, a jeśli masz kompilatora C++ 0x, a następnie można użyć zmiennej liczbie argumentów szablony:

template <typename ...Dummy> struct foo; // base case, never instantiated! 

template <typename T> struct foo<T> { /*...*/ }; // partial spec. for one parameter 
template <typename T, typename U> struct foo<T, U> { /*...*/ }; // ditto for two 
0

jest to kod niesprawdzone, nie mam wersję doładowania poręczne, ale tu idzie zresztą

#include "boost/tuple.h" 

template <class T> 
class Blah; 

template <class T> 
class Blah< boost::tuple<T> > 
{ 
    void operator()(T arg); 
}; 

template <class T, class U> 
class Blah< boost::tuple<T, U> > 
{ 
    void operator()(T arg1, U arg2); 
}; 

itp itd

Powiązane problemy