首頁 >後端開發 >C++ >為什麼SFINAE無法偵測繼承的成員函數?

為什麼SFINAE無法偵測繼承的成員函數?

Barbara Streisand
Barbara Streisand原創
2024-11-06 15:34:02729瀏覽

Why Does SFINAE Fail to Detect Inherited Member Functions?

使用 SFINAE 繼承成員函數來偵測

SFINAE(取代失敗不是錯誤)允許偵測給定類別中的成員函數。但是,當應用於繼承的成員函數時,SFINAE 遇到限制,導致錯誤偵測。

為了說明此問題,請考慮以下程式碼:

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

在此範例中,has_foo 未能偵測 B 中從 A 繼承的 foo() 成員。

為了克服此限制,需要更精細的 SFINAE 技術。考慮以下解決方案:

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

結果:

true
true
false

此解決方案引入了一個基本混合類別 BaseMixin,它提供了 foo() 成員函數。透過檢查 mix-in 類別中是否存在 foo() 來偵測繼承的成員函數。該技術可以準確地偵測繼承的成員函數,包括那些繼承的多層深度。

以上是為什麼SFINAE無法偵測繼承的成員函數?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn