Maison >développement back-end >C++ >Pourquoi la recherche dépendante des arguments (ADL) échoue-t-elle avec les modèles de fonctions explicitement instanciés ?
Recherche de modèles ADL et de fonctions
Les modèles de fonctions jouent un rôle important dans la programmation C, permettant la réutilisation du code et les fonctionnalités génériques. Cependant, une limitation subtile survient lors de l'utilisation de la recherche dépendante des arguments (ADL) pour localiser des modèles de fonction dans des espaces de noms spécifiques.
Le problème se manifeste lorsque vous tentez d'appeler un modèle de fonction avec des arguments de modèle explicites, comme illustré dans le code suivant. extrait :
namespace ns { struct foo {}; template<int i> void frob(foo const&) {} void non_template(foo const&) {} } int main() { ns::foo f; non_template(f); // This is fine. frob<0>(f); // This is not. }
La raison de cet échec provient d'une clause spécifique de la norme C. Conformément à la norme C 03 14.8.1.6, ADL ne s'applique pas lors de l'appel de modèles de fonction avec des arguments de modèle explicites, sauf si un modèle de fonction portant ce nom est visible au moment de l'appel.
Dans l'exemple ci-dessus, il y a aucun modèle de fonction nommé frob n'est visible dans la portée actuelle lorsque frob<0>(f); est appelé. Par conséquent, ADL n'est pas déclenché et le compilateur ne parvient pas à trouver le modèle de fonction souhaité.
Pour contourner cette limitation, on peut spécifier explicitement l'espace de noms avant le modèle de fonction, comme indiqué ci-dessous :
ns::frob<0>(f);
Dans ce cas, ADL n'est pas nécessaire puisque le modèle de fonction est directement invoqué à partir de l'espace de noms contenant.
L'exemple de code suivant illustre davantage le comportement d'ADL avec des modèles de fonction :
namespace A { struct B { }; template<int X> void f(B); } namespace C { template<class T> void f(T t); } void g(A::B b) { f<3>(b); //ill-formed: not a function call A::f<3>(b); //well-formed C::f<3>(b); //ill-formed; argument dependent lookup // applies only to unqualified names using C::f; f<3>(b); //well-formed because C::f is visible; then // A::f is found by argument dependent lookup }
Dans cet exemple, le modèle de fonction f est défini dans les deux espaces de noms A et C. Lorsque l'appel f<3>(b); est créé, le compilateur vérifie d'abord la portée actuelle et ne trouve aucun modèle f visible. ADL est ensuite appliqué, mais comme f est un nom non qualifié, il ne peut pas trouver de modèles de fonction dans d'autres espaces de noms.
Pour appeler le modèle depuis l'espace de noms C, il faut qualifier explicitement le nom avec C::f ou en utilisant la directive comme démontré dans le code.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!