Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determining wether a class has a certain member? [duplicate]

Tags:

c++

templates

Possible Duplicate:
Possible for C++ template to check for a function’s existence?

I am trying to determine wether a type has a certain member. This is what i tried:

template <typename T,typename U=void>
class HasX
{
public:
    static const bool Result=false;
};

template <typename T>
class HasX<T,typename enable_if_c<(sizeof(&T::X)>0)>::type>
{
public:
    static const bool Result=true;
};


struct A
{
    int X();
};

struct B
{
    int Y();
};


int main()
{
    cout<<HasX<A>::Result<<endl; // 1
    cout<<HasX<B>::Result<<endl; // 0
}

It actually compiles and works on GCC, but VC gives error C2070: 'overloaded-function': illegal sizeof operand at the point of instanciation.

Is there something wrong with the code, and are there other ways to do this?

like image 934
uj2 Avatar asked Dec 05 '25 00:12

uj2


1 Answers

There is indeed:

typedef char (&no_tag)[1];
typedef char (&yes_tag)[2];

template < typename T, void (T::*)() > struct ptmf_helper {};
template< typename T > no_tag has_member_foo_helper(...);

template< typename T >
yes_tag has_member_foo_helper(ptmf_helper<T, &T::foo>* p);

template< typename T >
struct has_member_foo
{
    BOOST_STATIC_CONSTANT(bool
        , value = sizeof(has_member_foo_helper<T>(0)) == sizeof(yes_tag)
        );
};

struct my {};
struct her { void foo(); };

int main()
{
    BOOST_STATIC_ASSERT(!has_member_foo<my>::value);
    BOOST_STATIC_ASSERT(has_member_foo<her>::value);

    return 0;
} 

Copy-pasted from here.

Edit: Update the code, which is compliant AFAIK. Also note that you have to know the arguments of the return type of the method you're checking for.

like image 185
Staffan Avatar answered Dec 07 '25 15:12

Staffan