共用方式為


區域宣告名稱的名稱解析

樣本的名稱本身在參考時可以具有或不具有樣板引數。 在類別樣板的範圍內,名稱本身會參考樣板。 在樣板特製化或部分特製化的範圍內,個別本身可參考特製化或部分特製化。 使用適當的樣板引數可以參考樣板的其他特製化或部分特製化。

範例

下列程式碼顯示在特製化或部分特製化的範圍內,類別樣板的名稱 A 的不同解譯。

// template_name_resolution3.cpp
// compile with: /c
template <class T> class A {
   A* a1;   // A refers to A<T>
   A<int>* a2;  // A<int> refers to a specialization of A.
   A<T*>* a3;   // A<T*> refers to the partial specialization A<T*>.
};

template <class T> class A<T*> {
   A* a4; // A refers to A<T*>.
};

template<> class A<int> {
   A* a5; // A refers to A<int>.
};

在樣板參數和其他物件之間發生名稱衝突的情況下,樣板參數可以或無法隱藏。 下列規則可協助判斷優先順序。

樣板參數的範圍是從第一次出現的位置,一直到類別或函式樣板的結尾。 如果名稱再次出現在樣板引數清單或基底類別清單中,其會參考相同的類型。 在 Standard C++ 中,在相同範圍內不可以宣告與樣板參數相同的名稱。 Microsoft 擴充功能允許在樣板的範圍內重新定義樣板參數。 下列範例顯示在類別樣板的基底規格中使用樣板參數。

// template_name_resolution4.cpp
// compile with: /EHsc
template <class T>
class Base1 {};

template <class T>
class Derived1 : Base1<T> {};

int main() {
   // Derived1<int> d;
}

在類別樣板的外部定義樣板的成員函式時,可以使用不同的樣板參數名稱。 如果樣板成員函式定義使用與宣告不同的樣板參數名稱,而且在定義中使用的名稱與宣告的其他成員發生衝突,則會優先使用樣板宣告中的成員。

// template_name_resolution5.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;

template <class T> class C {
public:
   struct Z {
      Z() { cout << "Z::Z()" << endl; }
   };
   void f();
};

template <class Z>
void C<Z>::f() {
   // Z refers to the struct Z, not to the template arg;
   // Therefore, the constructor for struct Z will be called.
   Z z;
}

int main() {
   C<int> c;
   c.f();
}
  

在宣告樣板的命名空間外部定義樣板函式或成員函式時,樣板引數會優先於命名空間的其他成員名稱。

// template_name_resolution6.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;

namespace NS {
   void g() { cout << "NS::g" << endl; }

   template <class T> struct C {
      void f();
      void g() { cout << "C<T>::g" << endl; }
   };
};

template <class T>
void NS::C<T>::f() {
   g(); // C<T>::g, not NS::g
};

int main() {
   NS::C<int> c;
   c.f();
}
  

在樣板類別宣告外部的定義中,如果樣板類別具有未相依於樣板引數的基底類別,而且,如果基底類別或其中一個成員的名稱與樣板引數相同,則基底類別或成員名稱會隱藏樣板引數。

// template_name_resolution7.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;

struct B {
   int i;
   void print() { cout << "Base" << endl; }
};

template <class T, int i> struct C : public B {
   void f();
};

template <class B, int i>
void C<B, i>::f() {
   B b;   // Base class b, not template argument.
   b.print();
   i = 1; // Set base class's i to 1.
}

int main() {
   C<int, 1> c;
   c.f();
   cout << c.i << endl;
}
  

請參閱

參考

樣板和名稱解析