2013-03-20 7 views
7

Die Anwendung, die ich im Sinne habe, ist so etwas wie eine Vector<size> Klasse, in der ichIst es möglich, eine Funktion zu deklarieren, die zu einer singulären Instanz einer Vorlagenklasse gehört?

CrossProduct(const Vector<size>& other) 

nur für, wenn Größe ist 3. Ich weiß, es gibt Möglichkeiten, wie ich um ihn herum hacken ...

erklären will
  • Fügen Sie eine Funktionsdefinition nur für size = 3
  • lassen alle anderen Größen Linkerfehler
  • Sie ergeben eine statische assert zu Beginn des Verfahrens zu überprüfen, ob der Größe 3 ist

Gibt es eine Möglichkeit, die Elementfunktion für eine bestimmte Instanziierung nur ordnungsgemäß zu deklarieren?

+1

Sie sind auf der Suche nach Kompilierung-Unterstützung, oder wäre ein Laufzeitfehler Ihren Forderungen zu erzeugen? – Porkbutts

Antwort

5

Hier ist eine Möglichkeit, es zu tun:

template <class Type, size_t Size> 
struct EnableCrossProduct 
{ 

}; 

template <class Type> 
struct EnableCrossProduct<Type, 3> 
{ 
    void CrossProduct(const Type & other){} 
}; 

template <size_t Size> 
struct Vector : public EnableCrossProduct<Vector<Size>, Size> 
{ 
}; 
+2

Viel Spaß beim Wiederholen '// was auch immer'. – GManNickG

+0

Ich würde lieber nicht die gesamte Klasse neu schreiben, um eine oder zwei Funktionen hinzuzufügen. –

+1

@GManNickG Da gehen wir, behoben –

3

Wenn Sie die Größeninformationen zur Kompilierzeit erhalten, können Sie std :: enable_if verwenden.

template<int N> 
struct Vector 
{ 
    static const int size = N; 
    double data[N]; 
    // ... 

    template<class V> 
    double CrossProduct(const V& other, 
     typename std::enable_if< size == 3 && V::size == 3 >::type* = 0) const 
    { 
     // ... 
     return 0; 
    } 
}; 

void foo(const Vector<3>& v3, const Vector<4>& v4) 
{ 
    v3.CrossProduct(v3); // Ok 
    v3.CrossProduct(v4); // Compile-time error 
} 

Sie möchten vielleicht nur size == V::size diese Bedingung in der enable_if machen.

+0

Sowohl CrossProduct (v3) 'als auch' CrossProduct (v4) 'sind Kompilierzeitfehler ... es ist eine Memberfunktion. –

+0

Ihr zweites SFINAE-Beispiel ist nicht korrekt. Es wird zum Beispiel bei der Instanziierung von 'Vector <4>' fehlen, ohne dass man versucht,' CrossProduct' zu verwenden. Spezialisierung bedeutet auch, Informationen zu wiederholen ("// ...") oder auszumerzen. – GManNickG

+0

Beide Probleme behoben. – metal

2

Ich würde die static_assert Methode bevorzugen. Diese

  • führt zum klarsten Fehlermeldung
  • geeignet ist, da es keine Notwendigkeit für SFINAE ist
  • ist der einfachste Weg.
+1

Ja ... Es ist nett, aber es ist bedauerlich, dass es die Itellisense von Visual Studio verschmutzt. Eine kleine Beschwerde, ich weiß, aber es beeinflusst die Verwendbarkeit der Klasse ein wenig für meine Zwecke. –

+0

Es gibt Leute da draußen, die nicht mit Intellisense codieren (wie ich). Wenn sie Ihren Code verwenden, müssen Sie auch an sie denken. – ipc

+1

Idealerweise würde ich eine Lösung finden, die den Bedürfnissen beider Parteien entspricht. Scheint aber unwahrscheinlich. Es tat nicht weh zu fragen =) –

Verwandte Themen