Udostępnij za pośrednictwem


Rozpoznawanie nazwy dla lokalnie zadeklarowanych nazw

Sama nazwa szablonu może być określona z lub bez argumentów szablonu.W zakresie szablonu klasy sama nazwa odnosi się do szablonu.W zakresie specjalizacji szablonu lub częściowej specjalizacji sama nazwa odnosi się do specjalizacji lub częściowej specjalizacji.Do innych specjalizacji lub częściowych specjalizacji szablonu można się również odwoływać, z argumentami odpowiedniego szablonu.

Przykład

Poniższy kod ilustruje, że nazwa szablonu klasy A jest interpretowana inaczej w zakresie specjalizacji lub częściowej specjalizacji.

// 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>.
};

W przypadku konflikt nazw między parametrem szablonu i parametrem innego obiektu szablonu może lub nie może być ukryty.Następujące reguły pomogą określić pierwszeństwo.

Parametr szablonu jest w zakresie od punktu, gdzie po raz pierwszy pojawia się aż do końca szablonu klasy lub funkcji.Jeśli nazwa pojawi się ponownie na liście argumentów szablonu lub na liście klas podstawowych, odnosi się do tego samego typu.W standardzie języka C++ żadna nazwa, która jest identyczna z parametrem szablonu nie może być zadeklarowana w tym samym zakresie.Rozszerzenie Microsoft pozwala przedefiniować parametr szablonu na nowo w zakresie szablonu.Poniższy przykład pokazuje użycie parametru szablonu w podstawowej specyfikacji szablonu klasy.

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

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

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

Podczas definiowania funkcji elementów członkowskich szablonu poza szablonem klasy, nazwę parametru może używać inny szablon.Jeśli definicja funkcji składowej szablonu używa innej nazwy parametru szablonu, niż ta zgłoszona, a nazwa używana w definicji konfliktów z innym członkiem deklaracji, członek w szablonie ma pierwszeństwo.

// 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();
}
  

Podczas definiowania funkcji szablonu lub funkcji członka poza obszarem nazw, w którym została zadeklarowany szablon, argument szablonu ma pierwszeństwo przed nazwami innych członków obszaru nazw.

// 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();
}
  

W definicji, które nie należą do szablonu deklaracji klasy, jeśli klasa szablonu ma klasę podstawową, która nie zależy od argumentu szablonu i jeśli klasa podstawowa lub jej członek ma taką samą nazwę jak argument szablonu, wtedy nazwa klasy lub członka ukrywa argument szablonu.

// 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;
}
  

Zobacz też

Informacje

Szablony i rozpoznawanie nazw