#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;
}
