Here is what I tested through http://webcompiler.cloudapp.net/ (live development branch for the Visual C++ compiler) :
#include <iostream>
using namespace std;
// the real stuff begins here
template < typename T > using is_char_t = int;
template < > using is_char_t< char > = char;
template < > using is_char_t< unsigned char > = char;
// the real stuff ends here
template < typename T > bool is_char(T const &)
{
return sizeof(is_char_t< T >) == 1;
}
int main()
{
cout << "is_char( 1.0) = " <<is_char(1.0) << endl;
cout << "is_char( 1) = " <<is_char(1) << endl;
cout << "is_char('1' ) = " <<is_char('1') << endl;
cout << "is_char('1'U) = " <<is_char(unsigned char('1')) << endl;
}
Doing so, I got:
Compiled with /EHsc /nologo /W4 main.cpp
main.cpp(7): error C2061: syntax error: identifier 'is_char_t'
main.cpp(8): error C2061: syntax error: identifier 'is_char_t'
Well I was not expecting for it to work.
Of course, I can reach the same goal with more boilerplate code:
namespace internal
{
template < typename T > struct is_char_t { using type = int; };
template < > struct is_char_t< char > { using type = char; };
template < > struct is_char_t< unsigned char > { using type = char; };
}
template < typename T > using is_char_t = typename internal::is_char_t< T >::type;
So my question is: is it an oversight or are there any reason that specializing a partial template type alias is too much complex to accept it in C++ grammar when "using" was extended to define a type alias ?