Maison > développement back-end > C++ > le corps du texte

Pourquoi SFINAE ne parvient-il pas à détecter les fonctions de membre héritées ?

Barbara Streisand
Libérer: 2024-11-06 15:34:02
original
624 Les gens l'ont consulté

Why Does SFINAE Fail to Detect Inherited Member Functions?

Détection des fonctions membres héritées avec SFINAE

SFINAE (Substitution Failure Is Not an Error) permet la détection des fonctions membres au sein d'une classe donnée . Cependant, lorsqu'il est appliqué aux fonctions membres héritées, SFINAE rencontre des limitations, entraînant de fausses détections.

Pour illustrer ce problème, considérons le code suivant :

<code class="cpp">// Does not correctly detect inherited member functions
template<typename T, typename Sig>                                 
struct has_foo {                     
    template <typename U, U> struct type_check;
    template <typename V> static char (&amp; chk(type_check<Sig, &amp;V::foo>*))[1];
    template <typename  > static char (&amp; chk(...))[2]; 
    static bool const value = (sizeof(chk<T>(0)) == 1);
};

struct A {
    void foo();
};

struct B : A {};

int main()
{
    using namespace std;
    cout << boolalpha << has_foo<A, void (A::*)()>::value << endl; // true
    cout << boolalpha << has_foo<B, void (B::*)()>::value << endl; // false
}
Copier après la connexion

Dans cet exemple, has_foo ne parvient pas à détecter le membre foo() hérité de B à partir de A.

Pour surmonter cette limitation, une technique SFINAE plus raffinée est nécessaire. Considérez la solution suivante :

<code class="cpp">template <typename Type> 
class has_foo
{ 
   class yes { char m;}; 
   class no { yes m[2];}; 
   struct BaseMixin 
   { 
     void foo(){} 
   }; 
   struct Base : public Type, public BaseMixin {}; 
   template <typename T, T t>  class Helper{}; 
   template <typename U> 
   static no deduce(U*, Helper<void (BaseMixin::*)(), &amp;U::foo>* = 0); 
   static yes deduce(...); 
public: 
   static const bool result = sizeof(yes) == sizeof(deduce((Base*)(0))); 
}; 

// Usage
struct A {
    void foo();
};

struct B : A {};

struct C {};

int main()
{
    using namespace std;
    cout << boolalpha << has_foo<A>::result << endl;
    cout << boolalpha << has_foo<B>::result << endl;
    cout << boolalpha << has_foo<C>::result;
}</code>
Copier après la connexion

Résultat :

true
true
false
Copier après la connexion

Cette solution introduit une classe de mixage de base, BaseMixin, qui fournit la fonction membre foo(). Les fonctions membres héritées sont détectées en vérifiant l'existence de foo() dans la classe mix-in. Cette technique permet une détection précise des fonctions de membre héritées, y compris celles héritées de plusieurs niveaux en profondeur.

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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!