2015-10-13 7 views
12

A-Klasse:Verschachtelte Klassen-Template Spezialisierung

template<typename C, typename T> 
class A 
{ 
    template <typename U> 
    class Nested{}; 

    Nested<T> n; 
}; 

Und ich will Nested spezialisieren. Hier ist, was ich versucht:

template<typename C, typename T> 
class A 
{ 
    template <typename U> 
    class Nested{}; 

    template <> 
    class Nested<int>{}; // by my logic this should work by I have a compilation error "explicit specialization in non-namespace scope 'class A<C, T>'" 

    Nested<T> n; 
}; 

Mein nächster Versuch:

template<typename C, typename T> 
class A 
{ 
    template <typename U> 
    class Nested{}; 

    Nested<T> n; 
}; 

template<> 
A<>::Nested<int>{}; // What is the correct syntax to do it here? Now I have an error "wrong number of template arguments (0, should be 2)" 

hier auf Stackoverflow ich eine Lösung gefunden:

template<typename C, typename T> 
class A 
{ 
    template <typename U, bool Dummy = true> 
    class Nested{}; // why need of this Dummy?? 

    template <bool Dummy> 
    class Nested<int, Dummy>{}; // why need to provide an argument?? 

    Nested<T> n; 
}; 

Es funktioniert perfekt, aber ich kann nicht verstehen, wie. Warum ein Dummy-Template-Argument angeben? Warum kann ich die rohe Spezialisierung template<> class Nested<int, true>{} oder template<> class Nested<int>{} nicht verwenden?

Antwort

12

Es ist verboten, explizite Spezialisierung in Klasse-Bereich zu erstellen:

Eine explizite Spezialisierung wird in einem Namespace deklariert wird die spezialisierte Vorlage einschließen.

Aber es ist nicht zu schaffen, teilweise Spezialisierung verboten:

Eine Klasse Vorlage partielle Spezialisierung erklärt werden kann oder neu deklarierte in jedem Namensraum, in welchem ​​Umfang die Definition definiert werden kann (14.5.1 und 14,5 .2).

dieser

template <bool Dummy> 
class Nested<int, Dummy>{}; // why need to provide an argument?? 

ist teilweise Spezialisierung und es erlaubt, solche Spezialisierung in Klasse-Bereich zu erstellen. Sie können die geschachtelte Klasse in nicht spezialisierten äußeren Klassen auch nicht vollständig spezialisieren. Sie können dies tun:

template<> 
template<> 
class A<int, double>::Nested<int> 
{ 
}; 

aber Sie können nicht tun

template<typename C, typename T> 
template<> 
class A<C, T>::Nested<int> 
{ 
}; 
1

ich es geschafft, dieses zu erhalten, zu arbeiten, indem sie den gesamten Inhalt der spezialisierten Template-Klasse innerhalb der äußeren Klasse definieren. Somit sind alle Funktionen vollständig mit der Klassendefinition definiert. Keine externen Funktionsdefinitionen, da dies nicht zu komplementieren schien. I.e.

template <typename T, size_t N> 
class A 
{ 
private: 
    template <size_t M> 
    class B 
    { 
     ... 
    }; 

    template <> 
    class B<2> 
    { 
     ... 
    }; 
    ... etc 
}; 

Es funktionierte auf MS2015 mindestens. Der Code läuft einwandfrei.

+1

Ja, aber es läuft nicht auf gcc und clang. Loos wie Microsoft folgt nicht dem Standard. Oder vielleicht gibt es einen Compiler-Schalter. – nikitablack