2010-09-19 4 views
9
template<typename T1, typename T2> 
class Bimap { 
public: 
    class Data { 
    private: 
     template<typename T> Data& set(T); 
     template<> Data& set<T1>(typename T1 v) { /*...*/ } 
    }; 
}; 

Das hat mir den Fehler gibt:C++: Fehler "explizite Spezialisierung in nicht-Namespace scope"

error: explicit specialization in non-namespace scope 'class Bimap<T1, T2>::Data'

Ich verstehe, was der Fehler sagt. Aber warum kann ich das nicht tun? Und wie kann ich es reparieren?

+2

Beachten Sie, dass einige Compiler dies unterstützen werden. – Puppy

+1

In C++ können Sie eine Membervorlage nicht explizit spezialisieren, ohne die umschließende Klassenvorlage explizit zu spezialisieren. Was du versuchst (Spezialisierung), ist * nicht möglich *. Sie müssen Überladung verwenden. Oder das Ganze komplett neu gestalten. MSVC++ ist ein Compiler, der dies jedoch als Erweiterung erlaubt. – AnT

Antwort

14

Ein Weg, vergessen Vorlagen, Überlastung:

Data& set(T1 v) { /*...*/ } 

aber hier ist ein Trick, den ich manchmal verwenden

Sie Klassenvorlage innerhalb der Klasse spezialisieren können:

class { 
    template<typename T> 
    struct function_ { 
     static void apply(T); 
    }; 

    template<> 
    struct function_<int> { 
     ... 
    }; 

    template<typename T> 
    void function(T t) { return function_<T>::apply(t); } 
+0

+1, yeah, der einzige vernünftige Weg, um Funktionsvorlagenspezialisierungen richtig zu bekommen. –

+4

Sie * können eine verschachtelte Klassenvorlage innerhalb einer * normalen * Klasse explizit spezialisieren. Aber Sie * können nicht ausdrücklich eine geschachtelte Klassenvorlage innerhalb einer anderen * Klassenvorlage * spezialisieren. Die einzige Möglichkeit, Letzteres zu tun, besteht darin, * sowohl * die * einschließende Vorlage als auch die verschachtelte Vorlage explizit zu spezialisieren. – AnT

+0

@Andrey Ich war mir nicht sicher über die Template-Klasse innerhalb der Template-Klasse. jedenfalls kann eine Variation des Tricks wahrscheinlich gemacht werden – Anycorn

0

@Albert

Ich hatte ein ähnliches Problem, wenn ich eine benutzerdefinierte "Trim-Überschuss-Kapazität" hinzufügen wollte Behälter gemacht. Der Trick std :: vector swap und das Ändern der Deklaration des vorhandenen Containers waren keine gültigen Optionen. Also habe ich mit diesem kommen:

template <class T, bool isPtr> struct DeleteImp 
{ 
    static void Trim(T* to, unsigned int count); 
}; 

template <class T> struct DeleteImp<T, false>  
{ 
    static void Trim(T* to, unsigned int count) {} 
}; 

template <class T> struct DeleteImp<T, true>   
{ 
    static void Trim(T* to, unsigned int count) 
    { 
     for(unsigned int i=0; i<count; i++) 
      delete to[i]; 
    } 
}; 

verwendet von meinem Container wie folgt aus:

DeleteImp<T, TypeTraits<T>::isPointer>::Trim(buf + length, truelength-length); 

Sie auch diese resource prüfen wollen, können.

Verwandte Themen