#include <iostream>
using namespace std;
template<typename T> struct TypeReader { static std::string read() { return typeid(T).name(); } };
template<typename T> std::string read_type(T&) { return TypeReader<T>::read(); }
template<typename T> std::string read_type(const T&) { return TypeReader<const T>::read(); }
template<typename T> std::string read_type(volatile T&) { return TypeReader<volatile T>::read(); }
template<typename T> std::string read_type(const volatile T&) { return TypeReader<const volatile T>::read(); }
int main() {
std::cout << read_type<int(*(&)[42])()>() << std::endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKdGVtcGxhdGU8dHlwZW5hbWUgVD4gc3RydWN0IFR5cGVSZWFkZXIgeyBzdGF0aWMgc3RkOjpzdHJpbmcgcmVhZCgpIHsgcmV0dXJuIHR5cGVpZChUKS5uYW1lKCk7IH0gfTsKdGVtcGxhdGU8dHlwZW5hbWUgVD4gc3RkOjpzdHJpbmcgcmVhZF90eXBlKFQmKSB7IHJldHVybiBUeXBlUmVhZGVyPFQ+OjpyZWFkKCk7IH0KdGVtcGxhdGU8dHlwZW5hbWUgVD4gc3RkOjpzdHJpbmcgcmVhZF90eXBlKGNvbnN0IFQmKSB7IHJldHVybiBUeXBlUmVhZGVyPGNvbnN0IFQ+OjpyZWFkKCk7IH0KdGVtcGxhdGU8dHlwZW5hbWUgVD4gc3RkOjpzdHJpbmcgcmVhZF90eXBlKHZvbGF0aWxlIFQmKSB7IHJldHVybiBUeXBlUmVhZGVyPHZvbGF0aWxlIFQ+OjpyZWFkKCk7IH0KdGVtcGxhdGU8dHlwZW5hbWUgVD4gc3RkOjpzdHJpbmcgcmVhZF90eXBlKGNvbnN0IHZvbGF0aWxlIFQmKSB7IHJldHVybiBUeXBlUmVhZGVyPGNvbnN0IHZvbGF0aWxlIFQ+OjpyZWFkKCk7IH0KCgppbnQgbWFpbigpIHsKCXN0ZDo6Y291dCA8PCByZWFkX3R5cGU8aW50KCooJilbNDJdKSgpPigpIDw8IHN0ZDo6ZW5kbDsKCXJldHVybiAwOwp9
prog.cpp: In function ‘int main()’:
prog.cpp:12:42: error: no matching function for call to ‘read_type<int (* (&)[42])()>()’
std::cout << read_type<int(*(&)[42])()>() << std::endl;
^
prog.cpp:5:34: note: candidate: ‘template<class T> std::__cxx11::string read_type(T&)’
template<typename T> std::string read_type(T&) { return TypeReader<T>::read(); }
^~~~~~~~~
prog.cpp:5:34: note: template argument deduction/substitution failed:
prog.cpp:12:42: note: candidate expects 1 argument, 0 provided
std::cout << read_type<int(*(&)[42])()>() << std::endl;
^
prog.cpp:6:34: note: candidate: ‘template<class T> std::__cxx11::string read_type(const T&)’
template<typename T> std::string read_type(const T&) { return TypeReader<const T>::read(); }
^~~~~~~~~
prog.cpp:6:34: note: template argument deduction/substitution failed:
prog.cpp:12:42: note: candidate expects 1 argument, 0 provided
std::cout << read_type<int(*(&)[42])()>() << std::endl;
^
prog.cpp:7:34: note: candidate: ‘template<class T> std::__cxx11::string read_type(volatile T&)’
template<typename T> std::string read_type(volatile T&) { return TypeReader<volatile T>::read(); }
^~~~~~~~~
prog.cpp:7:34: note: template argument deduction/substitution failed:
prog.cpp:12:42: note: candidate expects 1 argument, 0 provided
std::cout << read_type<int(*(&)[42])()>() << std::endl;
^
prog.cpp:8:34: note: candidate: ‘template<class T> std::__cxx11::string read_type(const volatile T&)’
template<typename T> std::string read_type(const volatile T&) { return TypeReader<const volatile T>::read(); }
^~~~~~~~~
prog.cpp:8:34: note: template argument deduction/substitution failed:
prog.cpp:12:42: note: candidate expects 1 argument, 0 provided
std::cout << read_type<int(*(&)[42])()>() << std::endl;
^