Risoluzione dei nomi per tipi dipendenti

Usare typename per i nomi qualificati nelle definizioni di modello per indicare al compilatore che il nome completo specificato identifica un tipo. Per altre 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.");
}
Name resolved by using typename keyword.

La ricerca dei nomi dipendenti esamina i nomi sia dal contesto della definizione del modello, nell'esempio seguente, che il contesto trova myFunction(char)e dal contesto della creazione di istanze del modello. Nell'esempio seguente viene creata un'istanza del modello in main; pertanto, MyNamespace::myFunction è visibile dal punto di creazione di istanze e viene scelto come corrispondenza migliore. Se MyNamespace::myFunction è stato rinominato, in alternativa viene chiamato myFunction(char).

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

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

Output

Int MyNamespace::myFunction

Risoluzione dell'ambiguità del modello

Visual Studio 2012 applica le regole standard C++98/03/11 per la disambiguazione con la parola chiave "template". Nell'esempio seguente Visual Studio 2010 accetterebbe sia le linee non conformi che le righe conformi. Visual Studio 2012 accetta solo le righe conformi.

#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 risoluzione ambiguità è necessaria perché, per impostazione predefinita, in C++ si presuppone che AY::Rebind non sia un modello e quindi il compilatore interpreta "<" come minore di. È necessario indicare che Rebind è un modello in modo da poter analizzare correttamente "<" come parentesi angolare.

Vedi anche

Risoluzione dei nomi