2010-11-19 41 views
3

kullanarak ve bir şey çözemedim ben anahtar kelime "typename" ne zaman kullanmalıyım ..Ben küçük bir proje üzerinde son zamanlarda çalışıyoruz şablonları

Ben .h dosyası izni verildiğine bir typename şablonu kullanarak bir sınıf içerdi. O sınıfın içinde özel bir sınıf vardı. Ben So

template<typename T> 
Node* Something::Function1(int index) //Is the return type well written? 
{ 
     // returns the node at the specified index 
} 

template<typename T> 
int Something::Index(const T& id) //Is the parameter type well specified? 
{ 
     // returns the index of the node with the specified id 
} 

bugging (a .inl dosyada) sınıfı "şey"

İşte

bunu yaptığını nasıl fonksiyonlarını tanımlamak istediğinde

template <typename T> 
class Something 
{ 
public: 
     Something(); 
     ~Something(); 

     Node* Function1(int index); 
     int Index(const T& id); 


private: 
     class Node() 
     { 
       public: 
       T id; 

       //Imagine the rest for the Node 


     };  
}; 

sorun oluştu bölüm tanımları bölümüydü ... Derleyiciye dönüş türünün (bu durumda Düğüm *) typename şablonunu kullandığını söylemem gerekir mi (böyle: typename Node*)? Peki ya parametre? typename const Node&?

Temel olarak, işlev/parametrenin bir şablon kullansa ne zaman belirtmeliyim?

Zaman ayırdığınız için teşekkür ederiz.

+0

Lütfen sorunuza sinipets gönderin! – mmmmmmmm

+0

Snippet'lerle bağlantılar yayınladım. Snippet'larımın nasıl doğru girileceğini anlayamadım. – Pacane

cevap

2
template<typename T> 
typename Something<T>::Node * Something::Function1(int index) //Is the return type well written? 
{ 
     // returns the node at the specified index 
} 
+0

Tamam, ve diğer yöntemin parametre türü nedir? – Pacane

+3

'Düğüm 'yuvalanmış bir sınıf adıdır. Yani bir '' Something '' yönteminde kodlamadığınız sürece veya 'typename Something :: Node' adını kullandığınızda kullanamazsınız. Ve bir metod döndürme türü (sınıfın dışında tanımlanmış) henüz “bir şey” yönteminin “içinde” değil, bu yüzden derleyiciyi açıklığa kavuşturmak zorundasınız. Diğer yöntemde böyle bir sorun olmaz, çünkü derleyici her zaman 'ın ne anlama geldiğini bilir. – aschepler

+0

Açıklama için ve zaman ayırdığınız için teşekkür ederiz. – Pacane

3

basit kural: Class parçası şablon parametresine bağlıdır eğer, sen Class::Type sözdizimi kullanarak bir türünü adlandırmak typename anahtar kelimeyi her seferinde kullanmak gerekir. (Class bölümü, bir şablon parametresi olabilir veya sınıf şablonunuzda bir typedef olabilir.)

Düzenleme: Ayrıca yuvalanmış sınıf kapsam belirleme kuralları hakkında bazı karışıklık da var. Bu çoğunlukla typename sayısından bağımsızdır, bu yüzden şablon olmayan bir örnek verilmiştir.

class Outer { 
public: 
    class Inner { 
    }; 
    Inner* func(Inner* obj); 
}; 

Outer::Inner* func(Inner* obj) 
{ 
} 

Inner tam adı Outer::Inner olduğunu. Ancak, func bildiriminin tümü de dahil olmak üzere, Inner numaralı kısa adı, Outer sınıfının kapsamı dahilinde de kullanabilirsiniz. func tanımında, dönüş türü Outer kapsamında DEĞİLDİR, bu nedenle tam ad gerekli. Ama ('dan sonra, Outer kapsamındaki ARE işlev parametreleri, kısa adı tamamdır. Outer eşdeğer Something<T> olduğundan Something<T>::Node söylemek orijinal örnek şablon lık ile bu birleştiren

, sen typename anahtar kelime gerekir.

+0

, bu nedenle, işlev dizini tanımındaki parametre türü yazılmalıdır typename const Sınıf :: Node & id? – Pacane

+1

@Pacane: Bu, bir "T" veya "Düğüm" iletmek ister misiniz? Eğer bir 'Node' iletmek istiyorsanız, tam sürüm çalışır, ancak gerekli değildir, çünkü derleyici bir 'Something' yöntemini tanımladığınızı ve' const Node & 'nin iyi olacağını görür. – aschepler

+0

Açıklama için ve zaman ayırdığınız için teşekkür ederiz. – Pacane

5

Function1 için, derleyiciye Node'nin ne olduğunu bildirmeniz gerekir - bu durumda, Something<T>'un iç içe bir türü. T'a bağlı olduğu için (bağımlı bir isim), derleyiciye bunun bir tür olduğunu söylemeniz gerekir, bu yüzden bunu typename Something<T>::Node olarak yazmanız gerekir. Sorun şu ki, Something<T>::Node'un aslında bir tür olmaması (yani, Something<T>'u kısmen uzmanlaştırıyorsanız) için bazı T olabilir. const T& bir const T için sadece bir referanstır ve derleyici T bilir -

Index için, ne iyi.

+0

parametresi bir düğüm için bir işaretçi olsaydı, typename bölümünü tekrar belirtmem gerekiyordu, değil mi? – Pacane

+1

'Something ' içinde olduğunuz için 'Node *' yazabilirsiniz. Ancak, bunu açıkça yazdıysanız, '' Something :: Node * 'yerine' 'Something :: Node *' türünde bir adlandırma yapmanız gerekir. –

+0

Açıklama için ve zaman ayırdığınız için teşekkür ederiz. – Pacane

1

typename ve class şablon tipi parametre listesinden eşdeğerdir: dependent names bahsedilirken

template <class T> class C; 

typename gerekli olduğu durumda

template <typename T> class C; 

olarak aynıdır:

template <typename T> struct A { 
    typedef typename T::some_type container; 
}; 
+2

Aslında, typename ve class bir parametre listesine denk DEĞİLDİR. Şablon şablonu parametrelerini beklerken typename anahtar kelimesi 'class' yerini alamaz. –

+0

Evet, teşekkürler, bunu unutmuşum. Dilin sadece bir boo-boo olsa da - ben sadece bu durumda benim için aynı şeyi unuttum :) –

İlgili konular