#include <iostream>
using namespace std;
template<typename Type>
constexpr bool IsRawString()
{
return 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>()>>
{
static const int Index = 2;
};
template<typename Type>
struct Traits<Type, std::enable_if_t<std::is_pointer<Type>::value && !IsRawString<Type>()>>
{
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;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCgp0ZW1wbGF0ZTx0eXBlbmFtZSBUeXBlPgpjb25zdGV4cHIgYm9vbCBJc1Jhd1N0cmluZygpCnsKICAgIHJldHVybiBzdGQ6OmlzX3NhbWU8Y29uc3QgY2hhciosIFR5cGU+Ojp2YWx1ZSB8fCBzdGQ6OmlzX3NhbWU8Y2hhciosIFR5cGU+Ojp2YWx1ZTsKfQoKdGVtcGxhdGU8dHlwZW5hbWUgVHlwZSwgdHlwZW5hbWUgRW5hYmxlID0gdm9pZD4Kc3RydWN0IFRyYWl0cwp7CiAgICBzdGF0aWMgY29uc3QgaW50IEluZGV4ID0gMTsKfTsKCnRlbXBsYXRlPHR5cGVuYW1lIFR5cGU+CnN0cnVjdCBUcmFpdHM8VHlwZSwgc3RkOjplbmFibGVfaWZfdDxJc1Jhd1N0cmluZzxUeXBlPigpPj4KewogICAgc3RhdGljIGNvbnN0IGludCBJbmRleCA9IDI7Cn07Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBUeXBlPgpzdHJ1Y3QgVHJhaXRzPFR5cGUsIHN0ZDo6ZW5hYmxlX2lmX3Q8c3RkOjppc19wb2ludGVyPFR5cGU+Ojp2YWx1ZSAmJiAhSXNSYXdTdHJpbmc8VHlwZT4oKT4+CnsKICAgIHN0YXRpYyBjb25zdCBpbnQgSW5kZXggPSAzOwp9OwoKaW50IG1haW4oKQp7CiAgICBjb3V0IDw8IFRyYWl0czxpbnQ+OjpJbmRleCA8PCBlbmRsCiAgICAgICAgIDw8IFRyYWl0czxjaGFyKj46OkluZGV4IDw8IGVuZGwKICAgICAgICAgPDwgVHJhaXRzPGNvbnN0IGNoYXIqPjo6SW5kZXggPDwgZW5kbAogICAgICAgICA8PCBUcmFpdHM8dm9pZCo+OjpJbmRleCA8PCBlbmRsOwoKICAgIHJldHVybiAwOwp9Cg==