#include <iostream>
#define MAKE_TYPE_NAME(type) \
template <> \
struct typename_of<type> { \
constexpr static const char* value = #type; \
}
//
template < typename >
struct typename_of;
MAKE_TYPE_NAME( int );
MAKE_TYPE_NAME( double );
MAKE_TYPE_NAME( int(double) );
MAKE_TYPE_NAME( int(int,double) );
MAKE_TYPE_NAME( int(*)(double) );
MAKE_TYPE_NAME( int[10] );
MAKE_TYPE_NAME( int(*)[10] );
MAKE_TYPE_NAME( int(*[10])(double) );
//
template < typename T >
void foo()
{
std::cout << typename_of<T>::value << std::endl;
}
int main() {
foo<int>();
foo<double>();
foo<int(double)>();
foo<int(int,double)>();
foo<int(*)(double)>();
foo<int[10]>();
foo<int(*)[10]>();
foo<int(*[10])(double)>();
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKI2RlZmluZSBNQUtFX1RZUEVfTkFNRSh0eXBlKSAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgIHRlbXBsYXRlIDw+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgIHN0cnVjdCB0eXBlbmFtZV9vZjx0eXBlPiB7ICAgICAgICAgICAgICAgICAgICAgIFwKICAgICAgICBjb25zdGV4cHIgc3RhdGljIGNvbnN0IGNoYXIqIHZhbHVlID0gI3R5cGU7IFwKICAgIH0KCi8vCnRlbXBsYXRlIDwgdHlwZW5hbWUgPgpzdHJ1Y3QgdHlwZW5hbWVfb2Y7CgpNQUtFX1RZUEVfTkFNRSggaW50ICk7Ck1BS0VfVFlQRV9OQU1FKCBkb3VibGUgKTsKTUFLRV9UWVBFX05BTUUoIGludChkb3VibGUpICk7Ck1BS0VfVFlQRV9OQU1FKCBpbnQoaW50LGRvdWJsZSkgKTsKTUFLRV9UWVBFX05BTUUoIGludCgqKShkb3VibGUpICk7Ck1BS0VfVFlQRV9OQU1FKCBpbnRbMTBdICk7Ck1BS0VfVFlQRV9OQU1FKCBpbnQoKilbMTBdICk7Ck1BS0VfVFlQRV9OQU1FKCBpbnQoKlsxMF0pKGRvdWJsZSkgKTsKCgovLwp0ZW1wbGF0ZSA8IHR5cGVuYW1lIFQgPgp2b2lkIGZvbygpCnsKICAgIHN0ZDo6Y291dCA8PCB0eXBlbmFtZV9vZjxUPjo6dmFsdWUgPDwgc3RkOjplbmRsOwp9CgoKaW50IG1haW4oKSB7IAogICAgCiAgICBmb288aW50PigpOwogICAgZm9vPGRvdWJsZT4oKTsKICAgIAogICAgZm9vPGludChkb3VibGUpPigpOwogICAgZm9vPGludChpbnQsZG91YmxlKT4oKTsKICAgIGZvbzxpbnQoKikoZG91YmxlKT4oKTsKICAgIAogICAgZm9vPGludFsxMF0+KCk7CiAgICBmb288aW50KCopWzEwXT4oKTsKICAgIAogICAgZm9vPGludCgqWzEwXSkoZG91YmxlKT4oKTsKfQo=