3

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?

Community
  • 1
  • 1
uj2
  • 2,255
  • 2
  • 21
  • 32
  • 1
    Duplicate of [Possible for C++ template to check for a function's existence?](http://stackoverflow.com/questions/257288/possible-for-c-template-to-check-for-a-functions-existence), maybe take a look at [SFINAE to check for inherited member functions](http://stackoverflow.com/questions/1966362/sfinae-to-check-for-inherited-member-functions) as well. – Georg Fritzsche Jul 08 '10 at 00:41

1 Answers1

6

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.

Staffan
  • 1,769
  • 13
  • 15
  • Doesn't work on VC either for some reason. Gives `error C2065: 'foo' : undeclared identifier` on `has_member_foo_helper(int, void (T::*)() = &T::foo);` – uj2 Jul 08 '10 at 00:54
  • @uj2: I updated the code, try again! It compiles on GCC. – Staffan Jul 08 '10 at 01:04