Partager via


Résolution de noms 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.");
}

dx2zs2ee.collapse_all(fr-fr,VS.110).gifSortie

Name resolved by using typename keyword.

La recherche de nom pour les noms dépendants examine les noms des deux le contexte du modèle définition- dans l'exemple suivant, ce contexte rechercherait myFunction(char))et le contexte de l'instanciation du modèle.Dans l'exemple suivant, le modèle est instancié dans le principal ; par conséquent, MyNamespace::myFunction est visible du point d'instanciation et est choisi comme meilleure correspondance.Si MyNamespace::myFunction ont été renommés, myFunction(char) est appelé à la place.

Tous les noms sont résolus comme s'il s'agissait de noms dépendants.Toutefois, nous vous recommandons d'utiliser des noms qualifiés complets s'il existe un conflit possible.

//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(fr-fr,VS.110).gifSortie

Int MyNamespace::myFunction

dx2zs2ee.collapse_all(fr-fr,VS.110).gifDésambiguisation de modèle

Visual C++ dans Visual Studio 2012 applique les règles standard C++98/03/11 pour la désambiguisation avec le mot clé « modèle ».Dans l'exemple suivant, Visual C++ 2010 reçoit les lignes non conforme et les lignes de conformation. Visual C++ dans Visual Studio 2012 reçoit uniquement les lignes de conformation.

#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 désambiguisation est requise parce que, par défaut, C++ suppose qu' AY::Rebind n'est pas un modèle, et le compilateur interprète « < » suivant en tant que inférieur à. Elle doit savoir qu' Rebind est un modèle afin qu'il puisse analyser correctement « < » comme crochet pointu.

Voir aussi

Référence

Modèles et résolution de noms