ホームページ  >  記事  >  バックエンド開発  >  SFINAE が継承されたメンバー関数を検出できないのはなぜですか?

SFINAE が継承されたメンバー関数を検出できないのはなぜですか?

Barbara Streisand
Barbara Streisandオリジナル
2024-11-06 15:34:02625ブラウズ

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 は失敗します。 A から B に継承された 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

この解決策では、foo() メンバー関数を提供する基本ミックスイン クラス BaseMixin が導入されます。継承されたメンバー関数は、ミックスイン クラス内の foo() の存在をチェックすることで検出されます。この手法により、複数のレベルで継承されたメンバー関数を含む、継承されたメンバー関数を正確に検出できます。

以上がSFINAE が継承されたメンバー関数を検出できないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。