Heim > Backend-Entwicklung > C++ > Hauptteil

Warum erkennt SFINAE geerbte Mitgliedsfunktionen nicht?

Barbara Streisand
Freigeben: 2024-11-06 15:34:02
Original
624 Leute haben es durchsucht

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
}
Nach dem Login kopieren

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>
Nach dem Login kopieren

Ergebnis:

true
true
false
Nach dem Login kopieren

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!

Quelle:php.cn
Erklärung dieser Website
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
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!