2016-05-29 13 views
1

Ich versuche, eine Spezialisierung für ein Mitglied Betreiber eines Templat-struct wie folgt zu definieren:specilization einer Elementfunktion einer Templat-Klasse funktioniert nicht

template<typename T = double> 
struct vec2 { 
    T x, y; 

    vec2(const T x, 
     const T y) 
    : x{x}, y{y} {} 

    vec2(const T w) 
    : vec2(w, w) {} 

    vec2() 
    : vec2(static_cast<T>(0)) {} 

    friend ostream& operator<<(ostream& os, const vec2& v) { 
     os << "vec2<" << v.x << ", " << v.y << ">"; 
     return os; 
    } 

    vec2<T> operator%(const T f) const; 
}; 

template<> template<> 
vec2<int> vec2<int>::operator%(const int f) const { 
    return vec2(x % f, y % f); 
} 

template<> template<> 
vec2<double> vec2<double>::operator%(const double f) const{ 
    return vec2(std::fmod(x, f), std::fmod(y, f)); 
} 

int main() { 
    vec2 v1(5.0, 12.0); 
    vec2<int> v2(5, 12); 
    cout << v1 % 1.5 << v2 % 2 << endl; 
    return 0; 
} 

Ich bin vor zwei Probleme:

  • Compiler kann keine passende Erklärung für beide Fach % Betreiber finden

    error: template-id ‘operator%<>’ for ‘vec2<int> vec2<int>::operator%(int) const’ does not match any template declaration

  • Compiler kann nicht den Parameter Standardvorlage für Erklärung vec2 v1 verwenden und erwartet Vorlage Argumente dafür

    error: missing template arguments before ‘v1’

Jetzt sind diese nicht voll Spezialisierung der struct vec2? Also sollte ich in der Lage sein, die Mitgliederfunktion auch zu spezialisieren?

Wie löst man es?

Antwort

1

ist ein Versuch, ein Mitglied in einer anderen Spezialisierung zu spezialisieren. Da operator% keine Funktion Vorlage ist, müssen Sie nur eine template<> eine vollständige Spezialisierung der vec2, um anzuzeigen, z.B .:

template <> 
vec2<int> vec2<int>::operator%(const int f) const 
{ 
    return vec2(x % f, y % f); 
} 

vec2 eine Klassenvorlage, kein Typ. Um eine Art von einer Klasse-Vorlage, die Standardwerte ihre Template-Parameter zu erstellen, können Sie ein leeres Paar Klammern müssen:

vec2<> v1(5.0, 12.0); 
// ~^^~ 

oder ein typedef für sie erstellen:

typedef vec2<> vec2d; 
vec2d v1(5.0, 12.0); 
+0

neugierig Just, sollte nicht Die Konstruktorargumente helfen dem Compiler, auch den Template-Argumenttyp abzuleiten, in diesem Fall 'double'? – Samik

+0

@Samik-Klassenvorlagenargumente werden niemals aus Konstruktorargumentausdrücken abgeleitet und stehen auch nicht mit Ihrem Fall in Zusammenhang. Wie ich sagte "vec2", ist ein Name, der sich auf eine Klassenvorlage bezieht, nicht auf einen Typ –