#include <iostream>
#include <type_traits>
//this goes in some header so you can use it everywhere
template<typename T>
struct TypeSink{
using Type = void;
};
template<typename T>
using TypeSinkT = typename TypeSink<T>::Type;
//here is the use case
template<typename T, typename = void>
struct enable_if_has_bar{ };
template<typename T>
struct enable_if_has_bar<T, TypeSinkT<decltype(std::declval<T&>().*(&T::bar))>>
: std::decay<decltype(std::declval<T&>().*(&T::bar))>
{ };
struct S{
int bar;
};
struct K{
};
template<typename T, typename = typename enable_if_has_bar<T>::type>
void print(T){
std::cout << "has bar" << std::endl;
}
void print(...){
std::cout << "no bar" << std::endl;
}
static_assert(std::is_same<typename enable_if_has_bar<S>::type,int>::value,"");
int main(){
print(S{});
print(K{});
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CgovL3RoaXMgZ29lcyBpbiBzb21lIGhlYWRlciBzbyB5b3UgY2FuIHVzZSBpdCBldmVyeXdoZXJlCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CnN0cnVjdCBUeXBlU2lua3sKICAgIHVzaW5nIFR5cGUgPSB2b2lkOwp9Owp0ZW1wbGF0ZTx0eXBlbmFtZSBUPgp1c2luZyBUeXBlU2lua1QgPSB0eXBlbmFtZSBUeXBlU2luazxUPjo6VHlwZTsKCi8vaGVyZSBpcyB0aGUgdXNlIGNhc2UKdGVtcGxhdGU8dHlwZW5hbWUgVCwgdHlwZW5hbWUgPSB2b2lkPgpzdHJ1Y3QgZW5hYmxlX2lmX2hhc19iYXJ7IH07Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBUPgpzdHJ1Y3QgZW5hYmxlX2lmX2hhc19iYXI8VCwgVHlwZVNpbmtUPGRlY2x0eXBlKHN0ZDo6ZGVjbHZhbDxUJj4oKS4qKCZUOjpiYXIpKT4+CiAgOiBzdGQ6OmRlY2F5PGRlY2x0eXBlKHN0ZDo6ZGVjbHZhbDxUJj4oKS4qKCZUOjpiYXIpKT4KICB7IH07CiAgCnN0cnVjdCBTewogICBpbnQgYmFyOwp9OwpzdHJ1Y3QgS3sKCQp9OwoKdGVtcGxhdGU8dHlwZW5hbWUgVCwgdHlwZW5hbWUgPSB0eXBlbmFtZSBlbmFibGVfaWZfaGFzX2JhcjxUPjo6dHlwZT4Kdm9pZCBwcmludChUKXsKCXN0ZDo6Y291dCA8PCAiaGFzIGJhciIgPDwgc3RkOjplbmRsOwp9CnZvaWQgcHJpbnQoLi4uKXsKCXN0ZDo6Y291dCA8PCAibm8gYmFyIiA8PCBzdGQ6OmVuZGw7Cn0Kc3RhdGljX2Fzc2VydChzdGQ6OmlzX3NhbWU8dHlwZW5hbWUgZW5hYmxlX2lmX2hhc19iYXI8Uz46OnR5cGUsaW50Pjo6dmFsdWUsIiIpOwoKaW50IG1haW4oKXsKICAgIHByaW50KFN7fSk7CiAgICBwcmludChLe30pOwp9