使用 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中文网其他相关文章!