char!=(signed char), char!=(unsigned char)
<p>The code below compiles, but has different behavior for the char type than for the int types.</p>

<p>In particular</p>

<pre><code>   cout &lt;&lt; getIsTrue&lt; isX&lt;int8&gt;::ikIsX  &gt;() &lt;&lt; endl;
   cout &lt;&lt; getIsTrue&lt; isX&lt;uint8&gt;::ikIsX  &gt;() &lt;&lt; endl;
   cout &lt;&lt; getIsTrue&lt; isX&lt;char&gt;::ikIsX  &gt;() &lt;&lt; endl;
</code></pre>

<p>result in 3 instantiations of templates for three types: int8, uint8 and char. What gives?</p>

<p>The same is not true for ints: int and uint32 which result in the same template instantiation, and signed int another.</p>

<p>The reason seems to be that C++ sees char, signed char and unsigned char as three different types. Whereas int is the same as a signed int. Is this right or am I missing something?</p>

<pre><code>#include &lt;iostream&gt;

using namespace std;

typedef   signed char       int8;
typedef unsigned char      uint8;
typedef   signed short      int16;
typedef unsigned short     uint16;
typedef   signed int        int32;
typedef unsigned int       uint32;
typedef   signed long long  int64;
typedef unsigned long long uint64;

struct TrueType {};
struct FalseType {};

template &lt;typename T&gt;
struct isX
{
   typedef typename T::ikIsX ikIsX;
};


// This  int==int32 is ambiguous
//template &lt;&gt;            struct isX&lt;int  &gt;    { typedef FalseType ikIsX; };  // Fails
template &lt;&gt;            struct isX&lt;int32  &gt;  { typedef FalseType ikIsX; };
template &lt;&gt;            struct isX&lt;uint32 &gt;  { typedef FalseType ikIsX; };


// Whay isn't this ambiguous? char==int8
template &lt;&gt;            struct isX&lt;char  &gt;  { typedef FalseType ikIsX; };
template &lt;&gt;            struct isX&lt;int8  &gt;  { typedef FalseType ikIsX; };
template &lt;&gt;            struct isX&lt;uint8 &gt;  { typedef FalseType ikIsX; };


template &lt;typename T&gt; bool getIsTrue();
template &lt;&gt;           bool getIsTrue&lt;TrueType&gt;() { return true; }
template &lt;&gt;           bool getIsTrue&lt;FalseType&gt;() { return false; }

int main(int, char **t )
{
   cout &lt;&lt; sizeof(int8) &lt;&lt; endl;  // 1
   cout &lt;&lt; sizeof(uint8) &lt;&lt; endl; // 1
   cout &lt;&lt; sizeof(char) &lt;&lt; endl;  // 1

   cout &lt;&lt; getIsTrue&lt; isX&lt;int8&gt;::ikIsX  &gt;() &lt;&lt; endl;
   cout &lt;&lt; getIsTrue&lt; isX&lt;uint8&gt;::ikIsX  &gt;() &lt;&lt; endl;
   cout &lt;&lt; getIsTrue&lt; isX&lt;char&gt;::ikIsX  &gt;() &lt;&lt; endl;

   cout &lt;&lt; getIsTrue&lt; isX&lt;int32&gt;::ikIsX  &gt;() &lt;&lt; endl;
   cout &lt;&lt; getIsTrue&lt; isX&lt;uint32&gt;::ikIsX  &gt;() &lt;&lt; endl;
   cout &lt;&lt; getIsTrue&lt; isX&lt;int&gt;::ikIsX  &gt;() &lt;&lt; endl;

}
</code></pre>

<p>I'm using g++ 4.something</p>
