#include <iostream>
#include <typeinfo>
template <typename> struct trait;
template <> struct trait<char> {
using storage = char;
};
template <> struct trait<int> {
using storage = double;
};
template <> struct trait<float> {
// No storage
};
template <typename> struct void_t { using type = void; };
template <typename T, typename = void>
struct example_user
{
static void do_something() {
std::cout << "invoked on " << typeid(T).name() << " which doesn't have storage" << std::endl;
}
};
template <typename T>
struct example_user<T, typename void_t<typename trait<T>::storage>::type>
{
static void do_something() {
std::cout << "invoked on " << typeid(T).name() << " which does have storage of type "
<< typeid(typename trait<T>::storage).name()
<< std::endl;
}
};
int main() {
example_user<char>::do_something();
example_user<int>::do_something();
example_user<float>::do_something();
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZWluZm8+Cgp0ZW1wbGF0ZSA8dHlwZW5hbWU+IHN0cnVjdCB0cmFpdDsKCnRlbXBsYXRlIDw+IHN0cnVjdCB0cmFpdDxjaGFyPiB7Cgl1c2luZyBzdG9yYWdlID0gY2hhcjsKfTsKCnRlbXBsYXRlIDw+IHN0cnVjdCB0cmFpdDxpbnQ+IHsKCXVzaW5nIHN0b3JhZ2UgPSBkb3VibGU7Cn07Cgp0ZW1wbGF0ZSA8PiBzdHJ1Y3QgdHJhaXQ8ZmxvYXQ+IHsKCS8vIE5vIHN0b3JhZ2UKfTsKCnRlbXBsYXRlIDx0eXBlbmFtZT4gc3RydWN0IHZvaWRfdCB7IHVzaW5nIHR5cGUgPSB2b2lkOyB9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lID0gdm9pZD4Kc3RydWN0IGV4YW1wbGVfdXNlcgp7CglzdGF0aWMgdm9pZCBkb19zb21ldGhpbmcoKSB7CgkJc3RkOjpjb3V0IDw8ICJpbnZva2VkIG9uICIgPDwgdHlwZWlkKFQpLm5hbWUoKSA8PCAiIHdoaWNoIGRvZXNuJ3QgaGF2ZSBzdG9yYWdlIiA8PCBzdGQ6OmVuZGw7Cgl9Cn07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4Kc3RydWN0IGV4YW1wbGVfdXNlcjxULCB0eXBlbmFtZSB2b2lkX3Q8dHlwZW5hbWUgdHJhaXQ8VD46OnN0b3JhZ2U+Ojp0eXBlPgp7CglzdGF0aWMgdm9pZCBkb19zb21ldGhpbmcoKSB7CgkJc3RkOjpjb3V0IDw8ICJpbnZva2VkIG9uICIgPDwgdHlwZWlkKFQpLm5hbWUoKSA8PCAiIHdoaWNoIGRvZXMgaGF2ZSBzdG9yYWdlIG9mIHR5cGUgIgoJCSAgICAgICAgICA8PCB0eXBlaWQodHlwZW5hbWUgdHJhaXQ8VD46OnN0b3JhZ2UpLm5hbWUoKQoJCSAgICAgICAgICA8PCBzdGQ6OmVuZGw7Cgl9Cn07CgppbnQgbWFpbigpIHsKCWV4YW1wbGVfdXNlcjxjaGFyPjo6ZG9fc29tZXRoaW5nKCk7CglleGFtcGxlX3VzZXI8aW50Pjo6ZG9fc29tZXRoaW5nKCk7CglleGFtcGxlX3VzZXI8ZmxvYXQ+Ojpkb19zb21ldGhpbmcoKTsKCXJldHVybiAwOwp9