Maison  >  Article  >  développement back-end  >  Pourquoi SFINAE ne parvient-il pas à détecter les fonctions de membre héritées ?

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

Barbara Streisand
Barbara Streisandoriginal
2024-11-06 15:34:02625parcourir

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
}

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>

Résultat :

true
true
false

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!

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