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 ?

Pourquoi la recherche dépendante des arguments (ADL) échoue-t-elle avec les modèles de fonctions explicitement instanciés ?

DDD
Libérer: 2024-12-11 04:20:10
original
623 Les gens l'ont consulté

Why Does Argument Dependent Lookup (ADL) Fail with Explicitly Instantiated Function Templates?

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&amp;) {}
    void non_template(foo const&amp;) {}
}

int main() {
    ns::foo f;
    non_template(f); // This is fine.
    frob<0>(f); // This is not.
}
Copier après la connexion

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);
Copier après la connexion

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
}
Copier après la connexion

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!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal