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
Commentaires
https://aka.ms/ContentUserFeedback.
Bientôt disponible : Tout au long de 2024, nous allons supprimer progressivement GitHub Issues comme mécanisme de commentaires pour le contenu et le remplacer par un nouveau système de commentaires. Pour plus d’informations, consultezEnvoyer et afficher des commentaires pour