Heim  >  Artikel  >  Backend-Entwicklung  >  Warum erkennt SFINAE geerbte Mitgliedsfunktionen nicht?

Warum erkennt SFINAE geerbte Mitgliedsfunktionen nicht?

Barbara Streisand
Barbara StreisandOriginal
2024-11-06 15:34:02625Durchsuche

Why Does SFINAE Fail to Detect Inherited Member Functions?

Vererbung der Mitgliedsfunktionserkennung mit SFINAE

SFINAE (Substitution Failure Is Not an Error) ermöglicht die Erkennung von Mitgliedsfunktionen innerhalb einer bestimmten Klasse . Bei der Anwendung auf geerbte Mitgliedsfunktionen stößt SFINAE jedoch auf Einschränkungen, was zu falschen Erkennungen führt.

Um dieses Problem zu veranschaulichen, betrachten Sie den folgenden Code:

<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
}

In diesem Beispiel schlägt has_foo fehl Erkennen Sie das geerbte foo()-Mitglied in B von A.

Um diese Einschränkung zu überwinden, ist eine verfeinerte SFINAE-Technik erforderlich. Betrachten Sie die folgende Lösung:

<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>

Ergebnis:

true
true
false

Diese Lösung führt eine Basis-Mix-In-Klasse ein, BaseMixin, die die Mitgliedsfunktion foo() bereitstellt. Geerbte Memberfunktionen werden erkannt, indem die Existenz von foo() in der Mix-In-Klasse überprüft wird. Diese Technik ermöglicht die genaue Erkennung geerbter Mitgliedsfunktionen, einschließlich solcher, die mehrere Ebenen tief vererbt wurden.

Das obige ist der detaillierte Inhalt vonWarum erkennt SFINAE geerbte Mitgliedsfunktionen nicht?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn