Go to Google Groups Home    comp.lang.c++
Detecting a specific member function is defined

Paul Mensonides <leavi...@attbi.com>

Ioannis Vranos wrote:
> "Phlip" <phlip...@yahoo.com> wrote in message
> news:b4jqoi$dnj@dispatch.concentric.net...

>> Brian is not writing a Swap function.

>> He wants a template that expands one way if its argument has a given
>> method, and another way if it does not. I honestly can't tell if you
>> read the same post as I.

>> There probably is no way to do what he wants without passing some
>> kind of extra template into the main template. So, if he needed to
>> Foo instead of Swap, he'd write one of:

>>    Foo<MyAclass, policyWithMethod>();
>>    Foo<MyBclass, policyWithoutMethod>();

>> Now the question becomes this: How do you make the template
>> automatically select one or the other policy? The answer is you
>> can't.

Yes, you can:

#include <iostream>

template<class T> struct has_member_Swap;

template<class R, class C> class has_member_Swap<R C::*> {
    private:
        template<R C::*> struct helper;
        template<class T> static char check(helper<&T::Swap>*);
        template<class T> static char (& check(...))[2];
    public:
        enum { value = sizeof(check<C>(0)) == 1 };

};

struct A { };

struct B {
    void Swap(B&) throw();

};

int main() {
    std::cout
        << has_member_Swap<void (A::*)(A&) throw()>::value << '\n';
        << has_member_Swap<void (B::*)(B&) throw()>::value << &std::endl;
    return 0;

}

Deduction by SFINAE.  Non-class types can be excluded via:

template<class T> class is_class {
    private:
        template<class U> static char check(int U::*);
        template<class U> static char (& check(...))[2];
    public:
        enum { value = sizeof(check<T>(0)) == 1 };

};

Regards,
Paul Mensonides