为了账号安全,请及时绑定邮箱和手机立即绑定

SFINAE检查继承的成员函数

SFINAE检查继承的成员函数

C++
慕的地10843 2019-10-06 14:15:21
使用SFINAE,我可以检测给定类是否具有某些成员函数。但是,如果我想测试继承的成员函数怎么办?以下内容在VC8和GCC4中不起作用(即检测到A具有成员函数foo(),但不能B继承成员函数):#include <iostream>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}那么,有没有办法测试继承的成员函数?
查看完整描述

3 回答

?
蛊毒传说

TA贡献1895条经验 获得超3个赞

joshperry的回答非常聪明和优雅,但是(如后文所述)它不能正确检查foo()的签名,并且不能与基本类型(如int)一起使用:这会导致编译器错误。我将提出一种可以正确处理继承的成员并检查成员函数签名的技术。我将不做详细介绍,而是给您两个示例,并希望代码能说明一切。


范例1:

我们正在检查具有以下签名的成员:  T::const_iterator begin() const


template<class T> struct has_const_begin

{

    typedef char (&Yes)[1];

    typedef char (&No)[2];


    template<class U> 

    static Yes test(U const * data, 

                    typename std::enable_if<std::is_same<

                             typename U::const_iterator, 

                             decltype(data->begin())

                    >::value>::type * = 0);

    static No test(...);

    static const bool value = sizeof(Yes) == sizeof(has_const_begin::test((typename std::remove_reference<T>::type*)0));

};

请注意,它甚至检查方法的一致性,并且也适用于原始类型。(我的意思has_const_begin<int>::value是假的,不会引起编译时错误。)


例子2

现在我们正在寻找签名: void foo(MyClass&, unsigned)


template<class T> struct has_foo

{

    typedef char (&Yes)[1];

    typedef char (&No)[2];


    template<class U>

    static Yes test(U * data, MyClass* arg1 = 0,

                    typename std::enable_if<std::is_void<

                             decltype(data->foo(*arg1, 1u))

                    >::value>::type * = 0);

    static No test(...);

    static const bool value = sizeof(Yes) == sizeof(has_foo::test((typename std::remove_reference<T>::type*)0));

};

请注意,MyClass不一定是默认可构造的,也不必满足任何特殊概念。该技术也适用于模板成员。


我热切地等待对此的意见。


查看完整回答
反对 回复 2019-10-06
  • 3 回答
  • 0 关注
  • 522 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信