#include <iostream>
using namespace std;
template<typename Type>
using IsRawString =
std::integral_constant<bool, std::is_same<const char*, Type>::value || std::is_same<char*, Type>::value>;
template<typename Type, typename Enable = void>
struct Traits
{
static const int Index = 1;
};
template<typename Type>
struct Traits<Type, std::enable_if_t<IsRawString<Type>::value>>
{
static const int Index = 2;
};
template<typename Type>
struct Traits<Type, std::enable_if_t<std::is_pointer<Type>::value && !IsRawString<Type>::value>>
{
static const int Index = 3;
};
int main()
{
cout << Traits<int>::Index << endl
<< Traits<char*>::Index << endl
<< Traits<const char*>::Index << endl
<< Traits<void*>::Index << endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCgp0ZW1wbGF0ZTx0eXBlbmFtZSBUeXBlPgp1c2luZyBJc1Jhd1N0cmluZyA9CiAgICBzdGQ6OmludGVncmFsX2NvbnN0YW50PGJvb2wsIHN0ZDo6aXNfc2FtZTxjb25zdCBjaGFyKiwgVHlwZT46OnZhbHVlIHx8IHN0ZDo6aXNfc2FtZTxjaGFyKiwgVHlwZT46OnZhbHVlPjsKCnRlbXBsYXRlPHR5cGVuYW1lIFR5cGUsIHR5cGVuYW1lIEVuYWJsZSA9IHZvaWQ+CnN0cnVjdCBUcmFpdHMKewogICAgc3RhdGljIGNvbnN0IGludCBJbmRleCA9IDE7Cn07Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBUeXBlPgpzdHJ1Y3QgVHJhaXRzPFR5cGUsIHN0ZDo6ZW5hYmxlX2lmX3Q8SXNSYXdTdHJpbmc8VHlwZT46OnZhbHVlPj4KewogICAgc3RhdGljIGNvbnN0IGludCBJbmRleCA9IDI7Cn07Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBUeXBlPgpzdHJ1Y3QgVHJhaXRzPFR5cGUsIHN0ZDo6ZW5hYmxlX2lmX3Q8c3RkOjppc19wb2ludGVyPFR5cGU+Ojp2YWx1ZSAmJiAhSXNSYXdTdHJpbmc8VHlwZT46OnZhbHVlPj4KewogICAgc3RhdGljIGNvbnN0IGludCBJbmRleCA9IDM7Cn07CgppbnQgbWFpbigpCnsKICAgIGNvdXQgPDwgVHJhaXRzPGludD46OkluZGV4IDw8IGVuZGwKICAgICAgICAgPDwgVHJhaXRzPGNoYXIqPjo6SW5kZXggPDwgZW5kbAogICAgICAgICA8PCBUcmFpdHM8Y29uc3QgY2hhcio+OjpJbmRleCA8PCBlbmRsCiAgICAgICAgIDw8IFRyYWl0czx2b2lkKj46OkluZGV4IDw8IGVuZGw7CgogICAgcmV0dXJuIDA7Cn0K