Maison >développement back-end >C++ >Pourquoi SFINAE échoue-t-il pour les fonctions membres du modèle de classe ?

Pourquoi SFINAE échoue-t-il pour les fonctions membres du modèle de classe ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-11-04 22:18:02799parcourir

Why Does SFINAE Fail for Class Template Member Functions?

Échec de SFINAE pour les fonctions membres du modèle de classe

Le mécanisme d'échec de remplacement n'est pas une erreur (SFINAE), couramment utilisé dans la métaprogrammation de modèles, semble présenter un comportement particulier lorsqu'il est appliqué aux fonctions membres du modèle de classe.

Le problème

Considérez l'extrait de code suivant :

<code class="cpp">#include <type_traits>

struct A{};
struct B{};

template <typename T>
struct Foo
{
    // Conditional enable bar() for T == A
    typename std::enable_if<std::is_same<T, A>::value>::type
    bar()
    {}

    // Conditional enable bar() for T == B
    typename std::enable_if<std::is_same<T, B>::value>::type
    bar()
    {}
};</code>

Ce code tente de définir deux surcharges de bar() dans le modèle de classe Foo, avec SFINAE utilisé pour activer conditionnellement chaque surcharge en fonction de la valeur de T. Cependant, le code ne parvient pas à se compiler avec l'erreur suivante :

<code class="cpp">error: 'typename std::enable_if<std::is_same<T, B>::value>::type Foo<T>::bar()' cannot be overloaded</code>

L'explication

SFINAE est généralement utilisée pour activer ou désactiver les spécialisations de modèles en fonction des arguments du modèle. Cependant, SFINAE ne s'applique qu'aux arguments de modèle déduits, c'est-à-dire aux arguments qui sont automatiquement déduits lors de la résolution de la surcharge. Dans le cas des fonctions membres, les arguments du modèle ne sont pas déduits mais plutôt explicitement spécifiés lors de l'instanciation de la classe. Par conséquent, SFINAE n'est pas applicable aux fonctions membres.

La solution

Il existe deux manières principales de résoudre ce problème :

  • Utilisez des modèles de fonctions : Définissez des modèles de fonctions distincts pour chaque surcharge, comme indiqué ci-dessous :
<code class="cpp">template <typename T>
void bar(Foo<T><- A) {}

template <typename T>
void bar(Foo<T><- B) {}
  • Utilisez une spécialisation de modèle de classe explicite : Définissez des modèles de classe pour chaque surcharge, comme indiqué ci-dessous :
<code class="cpp">template <typename> struct Foo;

template <> struct Foo<A> { void bar() {} };
template <> struct Foo<B> { void bar() {} };</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!

Déclaration:
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