2011-09-02 57 views
2

我是從這個page閱讀這篇文章,所以讓我來介紹代碼:需要幫助理解本文有關模板

template <class T> class D: typename C<T>::Base { //#1 error 
    D(): typename C<T>::Base(typename C<T>::Base(0)) { } //#2 error, #3 correct 
    typename C<T> f() { //#4 error 
     typename C<T>::A* p; //#5 correct 
     A<T>::B * n; 
    } 
}; 
class Q{ 
    typename C<long>::A * p; // #6 error 
} 
template <class T, class U> class R{ 
    typename C<long>::A * p; // #7 optional 
} 

#3是正確的,但我想了解作者試圖傳達。他說:

typename#3:correct。這裏,typename用於消除參數的 類型。如果沒有typename,則表達式C :: Base(0) 將被視爲對稱爲Base的函數的調用。隨着 類型名稱的前綴,C ::基地(0)創建 Ç:: Base的類型的臨時對象與參數初始化0

另外,如果你看到上面那部分作者說一點:

typename關鍵字必須前綴一個從屬名稱時名稱 滿足以下三個規則:

1.It出現一個模板中

2. 這是合格//我無法在所有了解這條線結合在基類規範或成員初始化列表 不使用開始的這句話

3.It的對位。

我無法理解此行(上述#2)在所有的結合開始這句話的段落。你能解釋作者的含義嗎?

+0

你有問題嗎? –

+0

我把它清理了很多,我移動了我認爲**是塊引用的問題。 –

+0

@Kerrek:是的(閱讀粗體句子?),你說這是因爲你沒有看完整個我認爲*笑臉* –

回答

2

「合格」表示它不在同一範圍內,而是當前範圍的子範圍,這也取決於模板。例如,

template <class T> struct C { 
    typedef int b; 
} 

b是一個合格的id從標準(§14.6.3)

template<typename T> struct M { 
    typename C<T>::b bb; 
} 

相關報價在另一個模板如引用時:

合格-ID指的是嵌套名稱說明符取決於模板參數(14.6.2)的類型,其中 的前綴是關鍵字typename表示合格ID 表示一個類型,形成一個詳細類型說明符(7.1.5.3)。

而且§14.6.2:

A name used in a template declaration or definition and that is dependent on a template-parameter is 
assumed not to name a type unless the applicable name lookup finds a type name or the name is qualified 
by the keyword typename. [Example: 
    // no B declared here 
    class X; 
    template<class T> class Y { 
     class Z; // forward declaration of member class 
     void f() { 
      X* a1; // declare pointer to X 
      T* a2; // declare pointer to T 
      Y* a3; // declare pointer to Y<T> 
      Z* a4; // declare pointer to Z 
      typedef typename T::A TA; 
      TA* a5; // declare pointer to T’s A 
      typename T::A* a6; // declare pointer to T’s A 
      T::A* a7; // T::A is not a type name: 
      // multiply T::A by a7; ill-formed, 
      // no visible declaration of a7 
      B* a8; // B is not a type name: 
      // multiply B by a8; ill-formed, 
      // no visible declarations of B and a8 
     } 
    }; 
—end example] 

和§14.6。7:

Within the definition of a class template or within the definition of a member of a class template, the keyword 
typename is not required when referring to the unqualified name of a previously declared member 
of the class template that declares a type. The keyword typename shall always be specified when the 
member is referred to using a qualified name, even if the qualifier is simply the class template name. 
[Example: 
    template<class T> struct A { 
     typedef int B; 
     A::B b; // ill-formed: typename required before A::B 
     void f(A<T>::B); // ill-formed: typename required before A<T>::B 
     typename A::B g(); // OK 
    }; 

The keyword typename is required whether the qualified name is A or A<T> because A or A<T> are synonyms 
within a class template with the parameter list <T>. ] 
+0

你回答了'也''後面的問題,你可以告訴作者在說什麼在模板中'typename#3' –

+0

@ Mr.Anubis如果你留下'typename'並且只是做了'C :: Base(0)',它會認爲你試圖調用函數'C :: Base'當參數爲'0'時,當你試圖建立一個''C :: Base'的實例傳遞'0'到它的構造函數。 –

+0

但構造函數是我們需要調用來創建對象的函數,所以有什麼區別? – 2011-09-02 18:11:27

0

不知道這是否會幫助,但模板使用的例子:

template<typename TemplateVar> 
class SimpleTemplate 
{ 
    public: 
     TemplateVar Item; 

     void SetItem(TemplateVar &ItemCopy); 
     TemplateVar &GetItem(); 
}; 

template<typename TemplateVar> 
void SimpleTemplate<TemplateVar>::SetItem(TemplateVar &ItemCopy) 
{ 
    Item = ItemCopy; 
    return; 
} 

template<typename TemplateVar> 
TemplateVar &SimpleTemplate<TemplateVar>::GetItem() 
{ 
    return Item; 
} 

int main(int ArgC, char *ArgV[]) 
{ 
    SimpleTemplate<char> Test; 
    return 0; 
} 

隨意做任何你想要的代碼(甚至賣掉它,如果可以的話)。

+0

+1對於'隨意做任何你想要的代碼(甚至出售它,如果可以的話)。「 – 2011-09-02 19:07:09