Risoluzione dei nomi dei tipi dipendenti

Utilizzare typename per i nomi completi nelle definizioni dei modelli per indicare al compilatore che il nome completo specificato identifica un tipo.Per ulteriori informazioni, vedere typename.

// template_name_resolution1.cpp
#include <stdio.h>
template <class T> class X
{
public:
   void f(typename T::myType* mt) {}
};

class Yarg
{
public:
   struct myType { };
};

int main()
{
   X<Yarg> x;
   x.f(new Yarg::myType());
   printf("Name resolved by using typename keyword.");
}

dx2zs2ee.collapse_all(it-it,VS.110).gifOutput

Name resolved by using typename keyword.

La ricerca del nome per i nomi dipendenti vengono esaminati i nomi da entrambi il contesto del modello definizione- nell'esempio seguente, questo contesto cercherebbe myFunction(char)e il contesto della creazione di un'istanza del modello.Nell'esempio seguente, viene creata un'istanza del modello in principale, pertanto, MyNamespace::myFunction è visibile dal momento della creazione di istanze e viene selezionato come corrispondenza ottimale.Se MyNamespace::myFunction è stato rinominato, myFunction(char) viene chiamato anziché.

Tutti i nomi vengono risolti come se fossero nomi dipendenti.Tuttavia, è consigliabile utilizzare nomi completi se si verifica un conflitto possibile.

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

void myFunction(char)
{
   cout << "Char myFunction" << endl;
}

template <class T> class Class1
{
public:
   Class1(T i)
   {
      // If replaced with myFunction(1), myFunction(char)
      // will be called
      myFunction(i);
}
};

namespace MyNamespace
{
   void myFunction(int)
   {
      cout << "Int MyNamespace::myFunction" << endl;
   }
};

using namespace MyNamespace;

int main()
{
   Class1<int>* c1 = new Class1<int>(100);
}

dx2zs2ee.collapse_all(it-it,VS.110).gifOutput

Int MyNamespace::myFunction

dx2zs2ee.collapse_all(it-it,VS.110).gifDisambiguazione del modello

Visual C++ in Visual Studio 2012 applica le regole standard C++98/03/11 per disambiguazione con la parola chiave “modello„.Nell'esempio seguente, Visual C++ 2010 avrebbe accettato sia le righe non conformi alle linee conformantesi. Visual C++ in Visual Studio 2012 accetta solo le righe conformantesi.

#include <iostream>
#include <ostream>
#include <typeinfo>
using namespace std;

template <typename T> struct Allocator {
    template <typename U> struct Rebind {
        typedef Allocator<U> Other;
    };
};

template <typename X, typename AY> struct Container {
    #if defined(NONCONFORMANT)
        typedef typename AY::Rebind<X>::Other AX; // nonconformant
    #elif defined(CONFORMANT)
        typedef typename AY::template Rebind<X>::Other AX; // conformant
    #else
        #error Define NONCONFORMANT or CONFORMANT.
    #endif
};

int main() {
    cout << typeid(Container<int, Allocator<float>>::AX).name() << endl;
}

La conformità alle regole di disambiguazione è necessaria perché, per impostazione predefinita, C++ si presuppone che AY::Rebind non sia un modello e pertanto il compilatore interpreta successiva “<come„ Less Than. Deve sapere che Rebind è un modello in modo da poter analizzare correttamente “<„ come parentesi angolare.

Vedere anche

Riferimenti

Modelli e risoluzione dei nomi