使用 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 (& chk(type_check<Sig, &V::foo>*))[1]; template <typename > static char (& 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::*)(), &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中文網其他相關文章!