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

Pourquoi SFINAE échoue-t-il avec les fonctions membres dans les modèles de classe ?

Patricia Arquette
Patricia Arquetteoriginal
2024-11-05 04:26:02346parcourir

Why Does SFINAE Fail with Member Functions in Class Templates?

Fonction membre SFINAE dans les modèles de classe : une explication détaillée

Dans le monde du C, SFINAE (Substitution Failure Is Not An Error) permet optimisations des modèles en évitant les erreurs d'instanciation lors de la compilation. Cependant, lorsqu'il s'agit de fonctions membres de modèles de classe, SFINAE peut se comporter de manière inattendue.

Le problème avec la fonction membre SFINAE

Considérez le code suivant :

<code class="cpp">template <typename T>
struct Foo
{
    typename std::enable_if<std::is_same<T, A>::value>::type bar();
    typename std::enable_if<std::is_same<T, B>::value>::type bar();
};</code>

Contrairement aux attentes, ce code entraîne un message d'erreur. SFINAE ne fonctionne pas comme prévu pour les fonctions membres au sein d'un modèle de classe.

SFINAE et arguments de modèle déduits

Le nœud du problème réside dans la dépendance de SFINAE à l'égard des arguments de modèle déduits. . Cela ne fonctionne que lorsque l'argument du modèle est déduit de l'appel de fonction. Dans le cas des fonctions membres, les arguments de modèle ne sont pas déduits et sont fournis explicitement.

Une solution utilisant des arguments déduits

Pour résoudre le problème, nous pouvons modifier le codez comme suit :

<code class="cpp">template<typename T>
struct Foo
{
    template<typename U = T>
    typename std::enable_if<std::is_same<U,A>::value>::type bar()
    {
    }

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

Maintenant, lors de l'appel de Foo()(x), le compilateur déduit l'argument du modèle T et sélectionne la surcharge correcte en fonction de x. Cette approche permet à SFINAE de fonctionner comme prévu.

Alternative : spécialisation explicite des modèles de classe

Si la structure de la classe est cruciale et ne peut être modifiée, une solution alternative implique spécialisation explicite du modèle de classe :

<code class="cpp">template <typename> struct Foo;

template <> struct Foo<A> { void bar() {} };
template <> struct Foo<B> { void bar() {} };</code>

Ici, le compilateur sait exactement quelle spécialisation instancier en fonction du type fourni. Il ne s'appuie pas sur SFINAE pour la sélection des spécialisations.

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