El siguiente código compila, pero tiene un comportamiento diferente para el tipo de caracteres que para los tipos int.char! = (Char firmado), char! = (Char no firmado)
En particular
cout << getIsTrue< isX<int8>::ikIsX >() << endl;
cout << getIsTrue< isX<uint8>::ikIsX >() << endl;
cout << getIsTrue< isX<char>::ikIsX >() << endl;
resultado en 3 instanciaciones de plantillas para tres tipos: int8, uint8 y Char. ¿Lo que da?
Lo mismo no es cierto para ints: int y uint32 que dan como resultado la misma instanciación de plantilla, y se firman en otro int.
La razón parece ser que C++ ve char, signed char y unsigned char como tres tipos diferentes. Mientras que int es lo mismo que un int firmado. ¿Es correcto o me estoy perdiendo algo?
#include <iostream>
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 <typename T>
struct isX
{
typedef typename T::ikIsX ikIsX;
};
// This int==int32 is ambiguous
//template <> struct isX<int > { typedef FalseType ikIsX; }; // Fails
template <> struct isX<int32 > { typedef FalseType ikIsX; };
template <> struct isX<uint32 > { typedef FalseType ikIsX; };
// Whay isn't this ambiguous? char==int8
template <> struct isX<char > { typedef FalseType ikIsX; };
template <> struct isX<int8 > { typedef FalseType ikIsX; };
template <> struct isX<uint8 > { typedef FalseType ikIsX; };
template <typename T> bool getIsTrue();
template <> bool getIsTrue<TrueType>() { return true; }
template <> bool getIsTrue<FalseType>() { return false; }
int main(int, char **t)
{
cout << sizeof(int8) << endl; // 1
cout << sizeof(uint8) << endl; // 1
cout << sizeof(char) << endl; // 1
cout << getIsTrue< isX<int8>::ikIsX >() << endl;
cout << getIsTrue< isX<uint8>::ikIsX >() << endl;
cout << getIsTrue< isX<char>::ikIsX >() << endl;
cout << getIsTrue< isX<int32>::ikIsX >() << endl;
cout << getIsTrue< isX<uint32>::ikIsX >() << endl;
cout << getIsTrue< isX<int>::ikIsX >() << endl;
}
estoy usando g ++ 4.Algo
También debe tomar nota de que no hay garantía de que 'int8_t' va a ser un' 'char' firmado y uint8_t' va a ser un' char' sin firmar. En particular, en Solaris 'int8_t' es simplemente' char' si 'char' está firmado. En otras palabras, su código no podrá compilar allí. –
"int y uint32 que da como resultado la misma instanciación de la plantilla, y firmado en otro int", esto definitivamente debería ser al revés, ya que int está firmado. –