#include <iostream>
template <typename T>
struct has_typedef_foobar {
// Types "yes" and "no" are guaranteed to have different sizes,
// specifically sizeof(yes) == 1 and sizeof(no) == 2.
typedef char yes[1];
typedef char no[2];
template <typename C>
static yes& test(typename C::foobar*);
template <typename>
static no& test(...);
// If the "sizeof" of the result of calling test<T>(nullptr) is equal to sizeof(yes),
// the first overload worked and T has a nested type named foobar.
static const bool value = sizeof(test<T>(nullptr)) == sizeof(yes);
};
struct foo {
typedef float foobar;
};
int main() {
std::cout << std::boolalpha;
std::cout << has_typedef_foobar<int>::value << std::endl; // Prints false
std::cout << has_typedef_foobar<foo>::value << std::endl; // Prints true
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CnN0cnVjdCBoYXNfdHlwZWRlZl9mb29iYXIgewogICAgLy8gVHlwZXMgInllcyIgYW5kICJubyIgYXJlIGd1YXJhbnRlZWQgdG8gaGF2ZSBkaWZmZXJlbnQgc2l6ZXMsCiAgICAvLyBzcGVjaWZpY2FsbHkgc2l6ZW9mKHllcykgPT0gMSBhbmQgc2l6ZW9mKG5vKSA9PSAyLgogICAgdHlwZWRlZiBjaGFyIHllc1sxXTsKICAgIHR5cGVkZWYgY2hhciBub1syXTsKCiAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgQz4KICAgIHN0YXRpYyB5ZXMmIHRlc3QodHlwZW5hbWUgQzo6Zm9vYmFyKik7CgogICAgdGVtcGxhdGUgPHR5cGVuYW1lPgogICAgc3RhdGljIG5vJiB0ZXN0KC4uLik7CgogICAgLy8gSWYgdGhlICJzaXplb2YiIG9mIHRoZSByZXN1bHQgb2YgY2FsbGluZyB0ZXN0PFQ+KG51bGxwdHIpIGlzIGVxdWFsIHRvIHNpemVvZih5ZXMpLAogICAgLy8gdGhlIGZpcnN0IG92ZXJsb2FkIHdvcmtlZCBhbmQgVCBoYXMgYSBuZXN0ZWQgdHlwZSBuYW1lZCBmb29iYXIuCiAgICBzdGF0aWMgY29uc3QgYm9vbCB2YWx1ZSA9IHNpemVvZih0ZXN0PFQ+KG51bGxwdHIpKSA9PSBzaXplb2YoeWVzKTsKfTsKCnN0cnVjdCBmb28geyAgICAKICAgIHR5cGVkZWYgZmxvYXQgZm9vYmFyOwp9OwoKaW50IG1haW4oKSB7CiAgICBzdGQ6OmNvdXQgPDwgc3RkOjpib29sYWxwaGE7CiAgICBzdGQ6OmNvdXQgPDwgaGFzX3R5cGVkZWZfZm9vYmFyPGludD46OnZhbHVlIDw8IHN0ZDo6ZW5kbDsgICAvLyBQcmludHMgZmFsc2UKICAgIHN0ZDo6Y291dCA8PCBoYXNfdHlwZWRlZl9mb29iYXI8Zm9vPjo6dmFsdWUgPDwgc3RkOjplbmRsOyAgIC8vIFByaW50cyB0cnVlCn0=