2010-09-19 39 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) { /*...*/ } 
    }; 
}; 

hatası "olmayan ad kapsamında açık uzmanlaşma":C++: bana hata veriyor

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

hata ne söylediğini anlıyoruz. Ama bunu neden yapamıyorum? Ve bunu nasıl düzeltebilirim?

+2

Bazı derleyiciler bunu destekleyeceğine dikkat çekiyor. – Puppy

+1

C++ uygulamasında, üye sınıf şablonunu açık bir şekilde uzmanlaşmadan açıkça bir üye şablonunda uzmanlaşamazsınız. Ne yapmaya çalıştığınız (yani uzmanlaşma) * mümkün değil *. Aşırı yüklemeyi kullanmalısın. Ya da tüm şeyi tamamen yeniden tasarlayın. MSVC++, bunun bir uzantı olmasına izin veren bir derleyicidir. – AnT

cevap

14

bir yolu şablonları, aşırı yük unutmak:

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

ama burada bazen kullandığınız bir hiledir

sınıfta içinde sınıf şablonu uzmanlaşabilir

:

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, evet, fonksiyon şablonu uzmanlıklarını doğru olarak alabilmenin tek yoludur. –

+4

* * bir * sıradan * sınıfında iç içe geçmiş bir sınıf şablonunu açıkça uzmanlaştırabilirsiniz. Ancak, * başka bir * sınıf şablonu içinde * iç içe geçmiş bir sınıf şablonunu açıkça özelleştiremezsiniz *. İkincisini yapmanın tek yolu, * hem şablonun hem de iç içe geçmiş şablonun açık bir şekilde uzmanlaşmasını sağlamaktır. – AnT

+0

@Andrey Şablon sınıfının içindeki şablon sınıfından emin değildim. her halükarda, hile bazı değişiklikler muhtemelen yapılabilir – Anycorn

0

@Albert

Bir özelliğe "aşırı kapasite" eklemek istediğimde benzer bir sorun yaşadım konteyner yaptı. Std :: vector swap hilesi ve mevcut kapsayıcının beyanı değiştirilerek geçerli seçenekler mevcut değildi. Bu yüzden bu ile geldim:

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]; 
    } 
}; 

böyle benim konteyner tarafından kullanılan:

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

Ayrıca bu resource kontrol etmek isteyebilir.

İlgili konular