2009-08-23 7 views
7

chcę specjalizują następujących funkcji członka:szablon specjalizacji klasy szablonu

class foo { 
    template<typename T> 
    T get() const; 
}; 

Do drugiej klasy bar że zależy na szablonach, jak również.

Na przykład, chciałbym bar być std::pair z niektórych parametrów szablonu, coś takiego:

template<> 
std::pair<T1,T2> foo::get() const 
{ 
    T1 x=...; 
    T2 y=...; 
    return std::pair<T1,T2>(x,y); 
} 

Gdzie T1 i T2 są szablony, jak również. Jak to zrobić? O ile mi wiadomo, powinno być możliwe .

Więc teraz mogę zadzwonić:

some_foo.get<std::pair<int,double> >(); 

Pełne/odpowiedź ostateczna:

template<typename T> struct traits; 
class foo { 
    template<typename T> 
    T get() const 
    { 
     return traits<T>::get(*this); 
    } 
}; 

template<typename T> 
struct traits { 
    static T get(foo &f) 
    { 
     return f.get<T>(); 
    } 
}; 

template<typename T1,typename T2> 
struct traits<std::pair<T1,T2> > { 
     static std::pair<T1,T2> get(foo &f) 
     { 
       T1 x=...; 
       T2 y=...; 
       return std::make_pair(x,y); 
     } 
}; 
+0

Nie jest jasne, co masz na myśli. Czy chcesz specjalizacji, która ma zastosowanie, gdy T1 i T2 są szablonami? Lub kiedy są jakieś konkretne szablony? Lub kiedy są szablonami, a ich parametr jest określonym typem? – jalf

+0

Chodzi mi o to, że chcę specjalizować się w mojej funkcji dla innego określonego typu (np. Std :: pair), które również wymagają pewnych parametrów szablonu. – Artyom

+0

Sprawdź to: http://stackoverflow.com/questions/947943/template-specialisation-where-emplated-type-is-alsoa-a-template –

Odpowiedz

8

Nie można częściowo specjalizują się szablony funkcyjne, przepraszam, ale takie są zasady. Można zrobić coś takiego:

class foo { 
    ... 
}; 


template<typename T> 
struct getter { 
    static T get(const foo& some_foo); 
}; 

template<typename T1, typename T2> 
struct getter< std::pair<T1, T2> > { 
static std::pair<T1, T2> get(const foo& some_foo) { 
    T1 t1 = ...; 
    T2 t2 = ...; 
    return std::make_pair(t1, t2); 
}; 

a następnie nazwać jak

getter<std::pair<int, double> >::get(some_foo); 

chociaż. Być może będziesz musiał trochę pogubić się ze statkiem lub widocznością, jeśli get naprawdę potrzebuje być członkiem funkcji.

Wypracowanie na SBI jest sugestia:

class foo { 
    ... 
    template<typename T> 
    T get() const; 
}; 

template<typename T> 
T foo::get() const 
{ 
    return getter<T>::get(*this); 
    /*   ^-- specialization happens here */ 
} 

a teraz z powrotem do bycia w stanie powiedzieć

std::pair<int,double> p = some_foo.get<std::pair<int, double> >(); 
+1

Możesz. jednakże, uczyń 'getter' a (prawdopodobnie' prywatny') członkiem klasy i wywołaj go za pomocą normalnego szablonu funkcji członka. W ten sposób użytkownicy twojej klasy nie muszą przejmować się tym mechanizmem. – sbi

+0

@sbi, to świetny punkt. –

1

Musisz przeciążyć funkcję składową dla pary, jak w

template <T, V> std::pair<T, V> foo::get() 

W ogólnym przypadku będziesz musiał mieć możliwość rozróżnienia między różnymi przeciążeniami. W przypadku ujednolicenia jest to łatwe, ponieważ para jest szablonowana na 2 typy, podczas gdy oryginalny element był szablonem tylko na T.

Jeśli zamiast tego potrzebna jest specjalizacja dla np. Std :: vector, czyli dla kontenera z pojedynczym szablonem parametrów, musisz być ostrożny, ponieważ może to być mylące dla kompilatora, aby zrozumieć, jeśli chcesz instancję specjalizację szablonu, w którym szablon T jest std :: vector lub specjalizacji na przeciążenia,

template <T> std::<vector <T> foo::get() const 

składni proponowane nie może pracować, ponieważ jesteś całkowicie specjalizujący funkcję Członka,

template <>,

, ale pomijasz dwa nieokreślone typy, T1 i T2.

+0

To nie działa: "prototyp dla' std :: pair <_T1, _T2> foo :: get() 'nie pasuje do żadnej z klasy' foo', kandydatem jest: szablon T foo :: get() " – Artyom

+0

musiałbyś zadeklarować w klasie 'foo template std :: pair get() const;' a następnie nazwać coś takiego: 'std :: pair p_int = f.get (); ' – Francesco