title: char!=(signed char), char!=(unsigned char)
body: <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>