Partager via


Résolution du nom pour les types dépendants

Utilisez typename pour les noms qualifiés dans les définitions de modèle pour indiquer au compilateur que le nom qualifié donné identifie un type. Pour plus d’informations, consultez 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 recherche de noms dépendants examine les noms à partir du contexte de la définition du modèle , dans l’exemple suivant, ce contexte trouve myFunction(char)— et le contexte de l’instanciation du modèle. Dans l’exemple suivant, le modèle est instancié en main ; par conséquent, il MyNamespace::myFunction est visible à partir du point d’instanciation et est choisi comme meilleure correspondance. Si MyNamespace::myFunction était renommé, myFunction(char) serait appelé à la place.

Tous les noms sont résolus comme s'ils étaient des noms dépendants. Néanmoins, nous vous recommandons d'utiliser des noms complets en cas de conflit éventuel.

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

Sortie

Int MyNamespace::myFunction

Levée des ambiguïtés de modèle

Visual Studio 2012 applique les règles standard C++98/03/11 pour la désambiguation avec le mot clé « modèle ». Dans l’exemple suivant, Visual Studio 2010 accepte les lignes non conformes et les lignes conformes. Visual Studio 2012 accepte uniquement les lignes conformes.

#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é avec les règles de levée des ambiguïtés est requise car, par défaut, C++ suppose que AY::Rebind n'est pas un modèle. Par conséquent, le compilateur interprète le < suivant comme un signe Inférieur à. Il doit savoir si Rebind est un modèle afin de pouvoir analyser correctement < comme crochet angulaire.

Voir aussi

Résolution de noms