2013-06-04 33 views
7

Sınıf şablonunda tanımlanan statik üye işlevine erişmeye çalışıyorum. başlık dosyası TemplateTest.h olarak ben gibi birincil sınıf Şablon tanımlanmış:Statik üye işlevi sınıf şablonu uzmanlığı içinde

#include<iostream> 

template<class T, class U> 
struct TemplateTest 
{ 
public: 
    void static invoke(); 
    /*{ 

     std::cout << "Should not be called" << std::endl; 

    }*/ 
}; 
Ben bir uzmanlık koymak Sonra Kaynak TemplateTester.cpp File

:

#include "TemplateTest.h" 

template<> 
struct TemplateTest<int, bool> 
{ 
    static void invoke() 
    { 
     std::cout << "invoke<int, bool>" << std::endl; 
    } 
}; 

template struct TemplateTest<int, bool>; //instantiate to resolve linker issue 

açıkça böylece bağlayıcı giderir ile sınıf örneği doğru şekilde. Sürücü driver.cpp olarak

: Ben sürücü sınıfına bağlamak çalıştığımda g ile TemplateTest.cpp derlerken

include "TemplateTest.h" 

int main() 
{ 
    TemplateTest<int, bool>::invoke(); 
    return 0; 
} 

++ doğru nesne dosyası oluşturur ama benim bağlayıcı hatası "veriyor 'TemplateTest :: invoke() "

tanımlanmamış başvurular this one gibi diğer ilgili iletilerden geçtim ama bir işlev şablonuna erişmeyi denemiyorum.

Herhangi bir ipucu çok takdir edilmektedir.

+4

Uygulamayı başlık dosyasına taşıyın. Şablonun uygulamaları, bunları kullanarak tüm TU'ya görünür olmalıdır. –

cevap

5

Sen TemplateTester.cpp oluşturduğunuz nesne dosyası verdiğiniz uzmanlaşma için bir sembol içerecek haklısın. Bu durum, herhangi bir açık uzmanlık şablonun başlatılmasına neden olduğu ve iki katına çıktığı için açık bir örneğe (aslında gereksiz olan) eklediğinizden durum böyleydi. Ancak, driver.cpp derlendiğinde, derleyici, uzmanlığı bilmez, çünkü yalnızca TemplateTester.h'u dahil edersiniz ve uzmanlık burada belirtilmez. Yani derleyici , özel bir tanımı kullanmadan tabiki şablonunu başlatır, böylece probleminizi alırsınız.

(§14.7:

Standardı (bana göre İtalik) diyor.3/6) Bir şablon, bir üye şablonu veya bir sınıf şablonunun bir üyesi açık bir şekilde uzmanlaşırsa, o zaman, bu uzmanlığın ilk kullanımından önce, örtük bir somutlaşmanın gerçekleşmesine neden olacak şekilde, her uzmanlık birimindeki her çeviri biriminde bildirilmelidir. böyle bir kullanım gerçekleşir; teşhis gerekmez. Eğer program, açık bir uzmanlık için bir tanım sağlamazsa ya da uzmanlık, örtük bir somutlaşmanın gerçekleşmesine ya da üyenin bir sanal üye fonksiyonuna yol açacak şekilde kullanılırsa, program kötü biçimlendirilmiş, teşhis gerektirmez. Açıklanmış bir özelleştirme için bildirilen ancak tanımlı olmayan örtük bir örnek oluşturma asla. [...]

Yani hem yapmak gerekir, beyan ve driver.cpp çalışır zaman derleyici tarafından bilinen uzmanlık tanımı. Bunu yapmanın en iyi yolu, tüm uzmanlığı TemplateTester.h'a eklemek.

Not, yine, açık bir örneğinin aslında gerekli olmadığını unutmayın.

+1

Açıklama için teşekkürler @jogojapan. Bu aslında üzerinde çalıştığım şablon statik kitaplığının bir prototipidir. Şimdi neden başarısız olduğunu anlayabiliyorum sanırım derleyiciyi mutlu tutmak için tanımları değiştirebilirim. – jazaman

3

çeşitli sorunları vardır:

  • başlıkta statik yöntemini koymak istiyorsanız o zaman inline kullanın açıkça tamamen özelleşmiş şablon
  • örneğini gerekmez. Aksi takdirde başlıkta koymak
  • şablon uzmanlık birden çok örneği ve bağlayıcı sorunları almak ve
  • bir şey istemiyorsanız
  • bir şablona çağrılacak kaynak dosyalarında yöntemleri tanımlar, tanımlamak gerekmez o. Derleyici hataları alırsınız, bu da hataları daha önce yakalamak anlamına gelir.

// TemplateTest.h 
#include<iostream> 

template<class T, class U> 
struct TemplateTest; 
template<> 
struct TemplateTest<int, bool> 
{ 
    inline static void invoke() 
    { 
     std::cout << "invoke<int, bool>" << std::endl; 
    } 
}; 

// main.cpp 
include "TemplateTest.h" 

int main() 
{ 
    TemplateTest<int, bool>::invoke(); 
} 

bir başka yolu başlığını değiştirmek ve kaynak dosyasını eklemektir.

// TemplateTest.h 
#include<iostream> 

template<class T, class U> 
struct TemplateTest; 

template<> 
struct TemplateTest<int, bool> 
{ 
    static void invoke(); 
}; 

// TemplateTest.cpp 
#include "TemplateTest.h" 
void TemplateTest<int, bool>::invoke() 
{ 
    std::cout << "invoke<int, bool>" << std::endl; 
} 
+0

Teşekkürler @ BЈовић Aslında burada bir prototip bulmaya çalıştım. Açıkça belirtmeliyim onlara. Sınıf şablonları aslında bir statik kütüphanenin bir parçasıdır ve bu nedenle, ben hala örneklemeye ihtiyacım olacağını düşünüyorum. Ama haklısın, sınıftaki işlevi tanımlamamalıyım. Dışarıda yapılmalı. Bunu deneyeceğim ve sorunumu çözüp çözmediğini göreceğim. – jazaman

+0

(http://support.microsoft.com/downloads/default/default.asp?answer=1) Jazaman Hayır, tamamen özel şablonlar oluşturmanız gerekmez, çünkü bunlar normal (şablonlar hariç) sınıflar gibidir. Başlığınızı çeşitli yerlere eklerseniz, bağlayıcı hataları alırsınız. Diğer cevabı okuduktan sonra –

+0

anladım ki eğer tamamen ihtisas davası varsa bunu daha fazla yapmanıza gerek yok. – jazaman

İlgili konular