2010-05-12 6 views
5

Ich habe eine Template-Klasse Matrix. Ich möchte eine Funktion für den Typkomplex spezialisieren, wobei T alles sein kann. Ich habe es versucht:Spezialisierung eines Members einer Template-Klasse für eine Template-Klasse Parametertyp

6 template <typename T> 
    7 class Matrix { 
    8  public : 
    9    static void f(); 
10 };   
11 template<typename T> void Matrix<T>::f() { cout << "generic" << endl; } 
12 template<> void Matrix<double>::f() { cout << "double" << endl; } 
13 template<typename T> void Matrix<std::complex<T> >::f() { cout << "complex" << endl; } 

Zeile 13 kompiliert nicht. Wie kann ich das machen ?

+1

mögliche Duplikate von [Einen Klassenschablonenkonstruktor spezialisieren] (http://stackoverflow.com/questions/2672536/specializing-a-class-template-constructor) –

+0

Ich sehe nicht, wie das ein dup ist. –

+0

Er versucht, die Nicht-Template-Member-Funktion zu spezialisieren. Dasselbe in dieser Frage. –

Antwort

1

In der Tat fand ich einen cleveren Weg, um es durch Boost zu tun. Da ich auf Boost-abhängig zu sein, nicht meine Bibliothek will, hier ist der Code:

template <class T, T val> struct integral_constant 
{ 
     typedef integral_constant<T, val> type; 
     typedef T value_type; 
     static const T value = val; 
};  
typedef integral_constant<bool, true> true_type; 
typedef integral_constant<bool, false> false_type; 
template <typename T> struct is_complex : false_type{}; 
template <typename T> struct is_complex<std::complex<T> > : true_type{}; 

template <typename T> 
class Matrix { 
     public : 
      static void f() { f_(typename is_complex<T>::type()); } 
     private : 
      static void f_(true_type) { cout << "generic complex" << endl; } 
      static void f_(false_type) { cout << "generic real" << endl; } 
};   
template<> void Matrix<double>::f() { cout << "double" << endl; } 

Auf diese Weise kann ich Funktion Überlastung und Vorlage zur Erreichung meines Ziel verwenden.

0

Wie in der verknüpften Antwort beschreiben, was Sie tun müssen, ist die gesamte Klasse spezialisiert, anstatt die einfache Funktion:

#include <iostream> 
#include <complex> 
using namespace std; 

template <typename T> 
class Matrix { 
public : 
    static void f(); 
}; 

template<typename T> void Matrix<T>::f() { cout << "generic" << endl; } 
template<> void Matrix<double>::f() { cout << "double" << endl; } 

template <typename T> 
class Matrix<std::complex<T> > { 
public: 
    static void f() { cout << "complex" << endl; } 
}; 

int main(void) { 
    Matrix<complex<double> >::f(); 
    return 0; 
} 
+0

Ich verstehe nicht. Warum kann ich es leicht für doppelte, aber nicht für komplexe spezialisieren? Was ich will, ist genau zu vermeiden, die gesamte Klasse zu spezialisieren, da dies bedeuten würde, dass ich Code kopieren muss, der wiederverwendet werden soll. – Maxime

+0

Sie können auch f in eine andere Klasse extrahieren und spezialisieren, dass alles, was Sie wollen: Matrix könnte 'f()' als Specialized :: f (...) ' – UncleBens

3

In den Zeilen 11 und 12 Sie Erklärung expliziter Spezialisierung für eine hat Mitglied einer Klassenvorlage, die nach C++ Standard 14.7/3 erlaubt ist (14.5.2/2 enthält auch ein gutes Beispiel). In Zeile 13 versuchen Sie, eine Klassenvorlage teilweise zu spezialisieren, und das ist in dieser Form nicht erlaubt (das ist eine Teilspezialisierung, weil Sie den ganzen Typ std::complex<T> nicht kennen, weil er immer noch von T abhängt). Sie sollten die gesamte Klasse teilweise spezialisieren.

+0

als Assaf Lavie vorgeschlagen, kann dies nicht mit verwendet werden Template-Template-Parameter, ohne die gesamte Klasse teilweise zu spezialisieren? Eine Reihe von Funktionen wird gleich sein, es ist doppelt oder komplex oder float. Ich möchte nicht alle diese Funktionen duplizieren müssen. – Maxime

+0

Wahrscheinlich ist es eine gute Idee, alle generischen Funktionen in die Basisklasse zu verschieben und nur die geerbte Klasse zu spezialisieren. –

Verwandte Themen