2011-07-15 24 views
7

Anlamak istediğim şablon uzmanlığı konusunda bir sorunum var. Visual C++ 10.0 (2010) ile çalışıyorum. Ben "get" yöntemi uzmanlaşmış çünkü bağlayıcı bir nesne dosyasından almak gerekir, TeorideŞablon uzmanlığı bağlantı kurmada başarısız oluyor

class VariableManager 
{ 
public: 

    template<typename VarT> 
     VarT get(std::string const& name) const 
     { 
        // Some code... 
     } 

    // This method supposed to be fully evaluated, linkable method. 
    template<> 
     std::string get<std::string>(std::string const& name) const; 

private: 
    std::map<std::string, boost::any> mVariables; 
}; 

: Böyle bir sınıf var. Ben kaynak dosyada yöntemini yerleştirirseniz Bunun yerine, bağlayıcı ilişkin çözülemeyen referans hatası alıyorum:

template<> 
    std::string VariableManager::get<std::string>(std::string const& name) const 
      { 
       // Doing something... 
      } 

ben satır içi olarak başlık dosyasına bu yöntemi yerleştirirseniz, yapı gayet güzel gidiyor. Ben bu kadar bu şablon işlevleri anlıyorum:

 template<typename VarT> 
      VarT get(std::string const& name) const; 

derleyici arama kodlarına göre şablonu uzmanlaşmak mümkün olmayacaktır çünkü başlığında yer ama tam uzmanlaşma durumunda öyle olmalıdır Bu nedenle sınıflandırma uygulaması, özel şablon yöntemi zaten bir halk sembolü olarak var olmalıdır. Birisi bu konuda biraz ışık tutabilir mi?

cevap

10

Sizin analizi doğru - açık değerlerle belirtilen herhangi bir şablon parametresi vardır bir açık uzmanlaşmış işlev şablonu, bir fonksiyonun tam bir tanımını sağlar.

Projenizde açık uzmanlık tanımını içeren karşılık gelen .cpp dosyasını düzgün eklediyseniz, VC++ bir bağlayıcı hatası yükseltmemelidir. Standartlara uygunluk için, size, sınıfın dışarısında uzmanlık beyannamesini bildirmeniz gerektiğini unutmayın. Standart, kapsayıcı sınıftaki açık uzmanlıkları bildirmeyi yasaklar (ve diğer derleyiciler kodunuzu reddeder). Bu yüzden bana Ayrıca size sınıf vücudun iç get<std::string> çağrı unutmayın edelim yerine

class VariableManager 
{ 
public: 

    template<typename VarT> 
     VarT get(std::string const& name) const 
     { 
        // Some code... 
     } 

private: 
    std::map<std::string, boost::any> mVariables; 
}; 

// This method supposed to be fully evaluated, linkable method. 
template<> 
std::string VariableManager::get<std::string>(std::string const& name) const; 

böyle ihtisas ilan etme başlık dosyasını değiştirin. Bunun nedeni, böyle bir çağrının açık uzmanlık bildirimini henüz görmemesi ve dolayısıyla bu işlevi şablon tanımından başlatmayı denemesidir. Standart, bu tür bir kodun teşhisi gerekmeden, kötü biçimlendirilmiş hale getirir.

+0

Komik, ama standart uyum sorunu sorun oldu. Bildiriyi sınıftan çıkardım ve önerdiğin gibi uzmanlık-beyannameyi yaptım ve linker hiç sorun yaşamadı. Uzmanlıkların sınıfın kapsamı dışında ilan edilmesi gerektiğini hatırlamakta fayda var. Nazik yardımlarınız için teşekkürler! – progician

+0

Cevabınızı bulmak benim için gerçek bir şans. Şablon uzmanlığını bir sınıf içinde bırakıp derleyiciyi bulamıyorsa, derleyicinin yaptığı şey benim için hala bir gizem. Ancak, kesinlikle benim günümü kurtardın! – Nipheris

0

Şablonda uzmanlaşmak, derleyiciyi başlatması için zorlamıyor (GCC'nin yaptığı gibi); hala derleyiciye şablonu gerçekten başlatması için açık bir şekilde söylemeniz gerekir. Açık şablon örneği ile bunu yapabilirsiniz. Temel olarak, sadece kaynak dosyada bu ekleyin: template<> ile başlayan

template std::string VariableManager::get(const std::string& name) const; 
+0

Bu yanlış. O ihtiyacı o yüzden o ihtiyaç duymaz ne de şablon –

+1

litre olduğunu doğrulamak istiyorum, bu gerçekten yanlış, ama cevabını burada bırakıyorum, böylece diğerleri de yanlış olduğunu görebilsin –

0

Yöntem hala templateuzmanlık yöntem olarak kabul edilir. Yani bir başlık dosyasına koymak zorundasınız.

Bir uygulama dosyasına koymak istiyorsanız, aşırı yük'a yüklemeniz gerekir.

class VariableManager 
{ 
//... 
    VarT get(std::string const& name) const 
    {} 

    std::string get(std::string const& name) const; //overloading not specialization 
}; 
+0

Hayır sen yapmazsın. Reko'nun cevabına bakın. Ve "şablon uzmanlaşma yöntemi" ile ne demek istediğini anlamadım. –

+0

(** AMA ** Uzmanlık alanından aşırı yüklemeyi tavsiye ederim _any day_!) –

+0

@Tomalak, OP, sorudaki 'şablon' yöntemini 'uzmanlaştırmaya çalışıyor.Cevabım, başlık dosyalarında özel yöntemlerin açıklanması gerektiğidir. Daha fazlasını belirleyebilir misin, yanlış olan nedir? – iammilind

İlgili konular