2008-10-02 11 views
26

Der folgende Code:"ungültige Verwendung von unvollständigem Typ" Fehler mit partieller Vorlage Spezialisierung

template <typename S, typename T> 
struct foo { 
    void bar(); 
}; 

template <typename T> 
void foo <int, T>::bar() { 
} 

gibt mir den Fehler

invalid use of incomplete type 'struct foo<int, T>' 
declaration of 'struct foo<int, T>' 

(. Ich bin mit gcc) Ist meine Syntax für die partiellen Spezialisierung falsch? Beachten Sie, dass, wenn ich das zweite Argument entferne:

dann kompiliert es korrekt.

Antwort

32

Sie können eine Funktion nicht teilweise spezialisieren. Wenn Sie dies für eine Mitgliedsfunktion tun möchten, müssen Sie die gesamte Vorlage teilweise spezialisieren (ja, es ist irritierend). Um eine Funktion teilweise zu spezialisieren, benötigen Sie eine Problemumgehung in einer großen Vorlagenklasse. Vielleicht würde eine Matrizenstruktur (z. B. template <typename U = T> struct Nested) funktionieren. Oder Sie können versuchen, von einer anderen Vorlage zu lernen, die sich teilweise spezialisiert (funktioniert, wenn Sie die Notation this->member verwenden, sonst werden Sie auf Compilerfehler stoßen).

3

Wenn Sie teilweise einen Konstruktor spezialisiert sind, könnten Sie so etwas wie versuchen:

template <class T, int N> 
struct thingBase 
{ 
    //Data members and other stuff. 
}; 

template <class T, int N> struct thing : thingBase<T, N> {}; 

template <class T> struct thing<T, 42> : thingBase<T, 42> 
{ 
    thing(T * param1, wchar_t * param2) 
    { 
     //Special construction if N equals 42. 
    } 
}; 

Hinweis: Dies wurde anonymisiert von etwas, was ich bin auf. Sie können dies auch verwenden, wenn Sie eine Vorlagenklasse mit sehr vielen Mitgliedern haben und nur eine Funktion hinzufügen möchten.

5

Obwohl coppro bereits zwei Lösungen erwähnt hat und Anonymous die zweite, hatte ich einige Zeit gebraucht, um die erste zu verstehen. Vielleicht ist der folgende Code hilfreich für jemanden, der über diese Seite stolpert, die wie Google in Google immer noch einen hohen Stellenwert hat. Das Beispiel (ein Vektor/Array/einzelnes Element von numericT als dataT übergeben und dann über [] oder direkt darauf zugrei- fen) ist natürlich etwas erfunden, sollte aber zeigen, wie man tatsächlich einer Teilfunktion durch das Wrapping sehr nahe kommen kann in einer teilweise spezialisierten Klasse.

/* The following circumvents the impossible partial specialization of 
a member function 
actualClass<dataT,numericalT,1>::access 
as well as the non-nonsensical full specialisation of the possibly 
very big actualClass. */ 

//helper: 
template <typename dataT, typename numericalT, unsigned int dataDim> 
class specialised{ 
public: 
    numericalT& access(dataT& x, const unsigned int index){return x[index];} 
}; 

//partial specialisation: 
template <typename dataT, typename numericalT> 
class specialised<dataT,numericalT,1>{ 
public: 
    numericalT& access(dataT& x, const unsigned int index){return x;} 
}; 

//your actual class: 
template <typename dataT, typename numericalT, unsigned int dataDim> 
class actualClass{ 
private: 
    dataT x; 
    specialised<dataT,numericalT,dataDim> accessor; 
public: 
    //... for(int i=0;i<dataDim;++i) ...accessor.access(x,i) ... 
};