#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;
//use case
template<typename T, typename=void>
struct HasBarOfTypeInt : std::false_type{};
template<typename T>
struct HasBarOfTypeInt<T, TypeSinkT<decltype(std::declval<T&>().*(&T::bar))>> : std::is_same<typename std::decay<decltype(std::declval<T&>().*(&T::bar))>::type,int>{};
struct S{
int bar;
};
struct K{
};
template<typename T, typename = TypeSinkT<decltype(&T::bar)>>
void print(T){
std::cout << "has bar" << std::endl;
}
void print(...){
std::cout << "no bar" << std::endl;
}
int main(){
print(S{});
print(K{});
std::cout << "bar is int: " << HasBarOfTypeInt<S>::value << std::endl;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CgovL3RoaXMgZ29lcyBpbiBzb21lIGhlYWRlciBzbyB5b3UgY2FuIHVzZSBpdCBldmVyeXdoZXJlCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CnN0cnVjdCBUeXBlU2lua3sKICAgIHVzaW5nIFR5cGUgPSB2b2lkOwp9Owp0ZW1wbGF0ZTx0eXBlbmFtZSBUPgp1c2luZyBUeXBlU2lua1QgPSB0eXBlbmFtZSBUeXBlU2luazxUPjo6VHlwZTsKCi8vdXNlIGNhc2UKdGVtcGxhdGU8dHlwZW5hbWUgVCwgdHlwZW5hbWU9dm9pZD4Kc3RydWN0IEhhc0Jhck9mVHlwZUludCA6IHN0ZDo6ZmFsc2VfdHlwZXt9Owp0ZW1wbGF0ZTx0eXBlbmFtZSBUPgpzdHJ1Y3QgSGFzQmFyT2ZUeXBlSW50PFQsIFR5cGVTaW5rVDxkZWNsdHlwZShzdGQ6OmRlY2x2YWw8VCY+KCkuKigmVDo6YmFyKSk+PiA6IHN0ZDo6aXNfc2FtZTx0eXBlbmFtZSBzdGQ6OmRlY2F5PGRlY2x0eXBlKHN0ZDo6ZGVjbHZhbDxUJj4oKS4qKCZUOjpiYXIpKT46OnR5cGUsaW50Pnt9OwoKc3RydWN0IFN7CiAgIGludCBiYXI7Cn07CnN0cnVjdCBLewoJCn07Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBULCB0eXBlbmFtZSA9IFR5cGVTaW5rVDxkZWNsdHlwZSgmVDo6YmFyKT4+CnZvaWQgcHJpbnQoVCl7CglzdGQ6OmNvdXQgPDwgImhhcyBiYXIiIDw8IHN0ZDo6ZW5kbDsKfQp2b2lkIHByaW50KC4uLil7CglzdGQ6OmNvdXQgPDwgIm5vIGJhciIgPDwgc3RkOjplbmRsOwp9CgppbnQgbWFpbigpewogICAgcHJpbnQoU3t9KTsKICAgIHByaW50KEt7fSk7CiAgICBzdGQ6OmNvdXQgPDwgImJhciBpcyBpbnQ6ICIgPDwgSGFzQmFyT2ZUeXBlSW50PFM+Ojp2YWx1ZSA8PCBzdGQ6OmVuZGw7Cn0=