// LIBRARY
#define HasMember(NAME) \
template<class Class, typename Type = void> \
struct HasMember_##NAME \
{ \
typedef char (&yes)[2]; \
template<unsigned long> struct exists; \
template<typename V> static yes Check (exists<sizeof(static_cast<Type>(&V::NAME))>*); \
template<typename> static char Check (...); \
static const bool value = (sizeof(Check<Class>(0)) == sizeof(yes)); \
}; \
template<class Class> \
struct HasMember_##NAME<Class, void> \
{ \
typedef char (&yes)[2]; \
template<unsigned long> struct exists; \
template<typename V> static yes Check (exists<sizeof(&V::NAME)>*); \
template<typename> static char Check (...); \
static const bool value = (sizeof(Check<Class>(0)) == sizeof(yes)); \
}
// INSTANTIATE
HasMember(Foo);
// USAGE
struct A {
int Foo(float);
};
struct B : public A {
};
struct C {
unsigned int Foo(double);
};
struct D {
static int Foo(float);
};
static_assert(HasMember_Foo<A>::value, "A should have foo.");
static_assert(HasMember_Foo<B>::value, "B should inherit foo from A.");
static_assert(!HasMember_Foo<C, int (C::*)(float)>::value, "C should not have foo.");
static_assert(!HasMember_Foo<D, int (D::*)(float)>::value, "Ds static foo should be false.");
int main () {}
Ly8gTElCUkFSWQojZGVmaW5lIEhhc01lbWJlcihOQU1FKSBcCiAgdGVtcGxhdGU8Y2xhc3MgQ2xhc3MsIHR5cGVuYW1lIFR5cGUgPSB2b2lkPiBcCiAgc3RydWN0IEhhc01lbWJlcl8jI05BTUUgXAogIHsgXAogICAgdHlwZWRlZiBjaGFyICgmeWVzKVsyXTsgXAogICAgdGVtcGxhdGU8dW5zaWduZWQgbG9uZz4gc3RydWN0IGV4aXN0czsgXAogICAgdGVtcGxhdGU8dHlwZW5hbWUgVj4gc3RhdGljIHllcyBDaGVjayAoZXhpc3RzPHNpemVvZihzdGF0aWNfY2FzdDxUeXBlPigmVjo6TkFNRSkpPiopOyBcCiAgICB0ZW1wbGF0ZTx0eXBlbmFtZT4gc3RhdGljIGNoYXIgQ2hlY2sgKC4uLik7IFwKICAgIHN0YXRpYyBjb25zdCBib29sIHZhbHVlID0gKHNpemVvZihDaGVjazxDbGFzcz4oMCkpID09IHNpemVvZih5ZXMpKTsgXAogIH07IFwKICB0ZW1wbGF0ZTxjbGFzcyBDbGFzcz4gXAogIHN0cnVjdCBIYXNNZW1iZXJfIyNOQU1FPENsYXNzLCB2b2lkPiBcCiAgeyBcCiAgICB0eXBlZGVmIGNoYXIgKCZ5ZXMpWzJdOyBcCiAgICB0ZW1wbGF0ZTx1bnNpZ25lZCBsb25nPiBzdHJ1Y3QgZXhpc3RzOyBcCiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBWPiBzdGF0aWMgeWVzIENoZWNrIChleGlzdHM8c2l6ZW9mKCZWOjpOQU1FKT4qKTsgXAogICAgdGVtcGxhdGU8dHlwZW5hbWU+IHN0YXRpYyBjaGFyIENoZWNrICguLi4pOyBcCiAgICBzdGF0aWMgY29uc3QgYm9vbCB2YWx1ZSA9IChzaXplb2YoQ2hlY2s8Q2xhc3M+KDApKSA9PSBzaXplb2YoeWVzKSk7IFwKICB9CgovLyBJTlNUQU5USUFURQpIYXNNZW1iZXIoRm9vKTsKCi8vIFVTQUdFCnN0cnVjdCBBIHsKICBpbnQgRm9vKGZsb2F0KTsKfTsKCnN0cnVjdCBCIDogcHVibGljIEEgewp9OwoKc3RydWN0IEMgewogIHVuc2lnbmVkIGludCBGb28oZG91YmxlKTsKfTsKCnN0cnVjdCBEIHsKICBzdGF0aWMgaW50IEZvbyhmbG9hdCk7Cn07CgpzdGF0aWNfYXNzZXJ0KEhhc01lbWJlcl9Gb288QT46OnZhbHVlLCAiQSBzaG91bGQgaGF2ZSBmb28uIik7CnN0YXRpY19hc3NlcnQoSGFzTWVtYmVyX0ZvbzxCPjo6dmFsdWUsICJCIHNob3VsZCBpbmhlcml0IGZvbyBmcm9tIEEuIik7CgpzdGF0aWNfYXNzZXJ0KCFIYXNNZW1iZXJfRm9vPEMsIGludCAoQzo6KikoZmxvYXQpPjo6dmFsdWUsICJDIHNob3VsZCBub3QgaGF2ZSBmb28uIik7CnN0YXRpY19hc3NlcnQoIUhhc01lbWJlcl9Gb288RCwgaW50IChEOjoqKShmbG9hdCk+Ojp2YWx1ZSwgIkRzIHN0YXRpYyBmb28gc2hvdWxkIGJlIGZhbHNlLiIpOwoKaW50IG1haW4gKCkge30=