2012-10-16 8 views
6

Ich möchte eine mathematische Vektorvorlage schreiben. Ich habe eine Klasse, die Typ und Größe als Template-Argument akzeptiert, mit vielen mathematischen Methoden. Nun möchte ich Spezialisierungen schreiben, wo Vektor < 3> zum Beispiel x, y, z als Mitglieder hat, die sich auf Daten [0..3] beziehen.C++ - Verwenden Sie Standardvorlage als Basis für die Spezialisierung

Das Problem ist, dass ich nicht weiß, wie man eine Spezialisierung erstellt, die alles von der Standardvorlage erbt, ohne entweder eine Basisklasse zu erstellen oder alles zweimal zu schreiben.

Was ist der effizienteste Weg, dies zu tun?

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

Das Erstellen einer Basisklasse ist dort der typische Ansatz. –

Antwort

7

Irgendwie sollten Sie in der Lage sein, von der Standardimplementierung abzuleiten, aber Sie spezialisieren sich auf eine Instanz, also wie? Es sollte eine nicht spezialisierte Version sein, die Sie daraus ableiten können. So ist das einfach:

// 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

Während dies gut funktioniert, scheint es mir etwas klobig zu sein, einen internen Template-Parameter in einer externen Schnittstelle zu haben. – Cameron

+0

Benutzer verwenden nie diesen zusätzlichen Vorlagenparameter, natürlich haben Sie eine andere Option, die sowohl spezialisierte als auch Standardimplementierung von einer Basisklasse ableiten, die tatsächliche Implementierung enthalten! aber meiner Meinung nach ist das ein bisschen schwieriger als diese Technik! – BigBoss

+0

@BigBoss Schön, danke. – weltensturm

1

Betrachten Sie diese in ein wenig anders zu machen, aber Ziele werden erreicht, hinzufügen externe Schnittstelle - ich meine Standalone-Funktionen 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]; 
} 

Es gibt keinen großen Unterschied zwischen:

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

Und

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

Als Bonus - diese Schnittstelle funktioniert für passende Größen.

Verwandte Themen