#include <iostream>
#include <utility>
template <typename T, typename = size_t>
struct HasField_abc : std::false_type { };
template <typename T>
struct HasField_abc<T, decltype(sizeof(std::declval<T>().abc))> : std::true_type { };
template <typename T>
std::enable_if_t<HasField_abc<T>::value> get(T&)
{
std::cout << "Has abc" << std::endl;
// . . .
}
template <typename T>
std::enable_if_t<!HasField_abc<T>::value> get(T&)
{
std::cout << "Has no abc" << std::endl;
// . . .
}
struct Foo
{
std::string abc;
};
struct Bar
{
std::string ab;
};
int main()
{
Foo foo;
get(foo); // Has abc
Bar bar;
get(bar); // Has no abc
int i;
get(i); // Has no abc
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dXRpbGl0eT4KCnRlbXBsYXRlIDx0eXBlbmFtZSBULCB0eXBlbmFtZSA9IHNpemVfdD4Kc3RydWN0IEhhc0ZpZWxkX2FiYyA6IHN0ZDo6ZmFsc2VfdHlwZSB7IH07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4Kc3RydWN0IEhhc0ZpZWxkX2FiYzxULCBkZWNsdHlwZShzaXplb2Yoc3RkOjpkZWNsdmFsPFQ+KCkuYWJjKSk+IDogc3RkOjp0cnVlX3R5cGUgeyB9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CnN0ZDo6ZW5hYmxlX2lmX3Q8SGFzRmllbGRfYWJjPFQ+Ojp2YWx1ZT4gZ2V0KFQmKQp7CglzdGQ6OmNvdXQgPDwgIkhhcyBhYmMiIDw8IHN0ZDo6ZW5kbDsKCS8vIC4gLiAuCn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpzdGQ6OmVuYWJsZV9pZl90PCFIYXNGaWVsZF9hYmM8VD46OnZhbHVlPiBnZXQoVCYpCnsKCXN0ZDo6Y291dCA8PCAiSGFzIG5vIGFiYyIgPDwgc3RkOjplbmRsOwoJLy8gLiAuIC4KfQoKc3RydWN0IEZvbwp7CglzdGQ6OnN0cmluZyBhYmM7Cn07CgpzdHJ1Y3QgQmFyCnsKCXN0ZDo6c3RyaW5nIGFiOwp9OwoKaW50IG1haW4oKQp7CglGb28gZm9vOwoJZ2V0KGZvbyk7IC8vIEhhcyBhYmMKCglCYXIgYmFyOwoJZ2V0KGJhcik7IC8vIEhhcyBubyBhYmMKCglpbnQgaTsKCWdldChpKTsgLy8gSGFzIG5vIGFiYwp9