2012-10-16 14 views
6

Chcę napisać szablon matematyka wektorowych. Mam klasę, która przyjmuje typ i rozmiar jako argument szablonu, z wieloma metodami operacji matematycznych. Teraz chcę napisać specjalizacje gdzie wektor < 3> na przykład ma X, Y, Z jak członków, które odnoszą się do danych [0..3] odpowiednio.C++ - Użyj domyślnego szablonu jako podstawa do specjalizacji

Problem polega na tym, że nie wiem, jak utworzyć specjalizację która dziedziczy wszystko z domyślnym szablonem bez tworzenia albo klasę bazową lub pisząc wszystko dwa razy.

Jaki jest najbardziej wydajny sposób na zrobienie tego?

template<class Type, size_t Size> 
class Vector { 
    // stuff 
}; 

template<class T> 
class Vector<3,T>: public Vector { 
    public: 
     T &x, &y, &z; 
     Vector(): Vector<>(), x(data[0]), y(data[1]), z(data[2]){} 
     // and so on 
}; 
+2

Tworzenie klasy bazowej jest typowe podejście tam. –

Odpowiedz

7

W jakiś sposób powinieneś być w stanie wywnioskować z domyślnej implementacji, ale specjalizujesz się w instancji, więc w jaki sposób? powinna to być wersja nie specjalizowana, z której możesz czerpać. Więc to jest prosta:

// Add one extra argument to keep non-specialized version! 
template<class Type, size_t Size, bool Temp = true> 
class Vector { 
    // stuff 
}; 
// And now our specialized version derive from non-specialized version! 
template<class T> 
class Vector<T, 3, true>: public Vector<T, 3, false> { 
    public: 
     T &x, &y, &z; 
     Vector(): Vector<>(), x(data[0]), y(data[1]), z(data[2]){} 
     // and so on 
}; 
+0

Chociaż to działa dobrze, wydaje się nieco niezgrabne (dla mnie), aby mieć wewnętrzny parametr szablonu w interfejsie zewnętrznym. – Cameron

+0

Użytkownik nigdy nie używa tego dodatkowego parametru szablonu, oczywiście masz inną opcję, która zarówno implementacja specjalistyczna, jak i domyślna wywodzą się z klasy bazowej zawierającej rzeczywistą implementację! ale moim zdaniem to trochę trudniejsze niż ta technika! – BigBoss

+0

@BigBoss Miło, dziękuję. – weltensturm

1

Rozważyć to w trochę inny sposób, ale zostaną osiągnięte cele, Dodawanie interfejsu zewnętrznego - Znaczy samodzielna funkcja X(), Y(), Z():

template<class T, size_t S> 
T& x(Vector<T, S>& obj, typename std::enable_if<(S>=1)>::type* = nullptr) 
{ 
    return obj.data[0]; 
} 

template<class T, size_t S> 
T& y(Vector<T, S>& obj, typename std::enable_if<(S>=2)>::type* = nullptr) 
{ 
    return obj.data[1]; 
} 

template<class T, size_t S> 
T& z(Vector<T, S>& obj, typename std::enable_if<(S>=3)>::type* = nullptr) 
{ 
    return obj.data[2]; 
} 

nie ma duża różnica między:

Vector<T, 3>& obj 
return obj.x(); 

I

Vector<T, 3>& obj 
return x(obj); 

Jako bonus - ten interfejs działa na dopasowanie rozmiarów.

Powiązane problemy