c++ - usar - char!=(char firmado), char!=(char sin signo)
string c++ (4)
Aquí está su respuesta del estándar:
3.9.1 Tipos fundamentales [basic.fundamental]
Los objetos declarados como caracteres (
char
) deben ser lo suficientemente grandes como para almacenar cualquier miembro del conjunto de caracteres básicos de la implementación. Si un carácter de este conjunto se almacena en un objeto de carácter, el valor integral de ese objeto de carácter es igual al valor de la forma literal de un solo carácter de ese carácter. Se define en la implementación si un objetochar
puede contener valores negativos. Los caracteres se pueden declarar explícitamenteunsigned
osigned
. Plainchar
,signed char
yunsigned char
son tres tipos distintos. Unchar
, unsigned char
y ununsigned char
ocupan la misma cantidad de almacenamiento y tienen los mismos requisitos de alineación ( basic.types ); es decir, tienen la misma representación de objeto. Para los tipos de caracteres, todos los bits de la representación del objeto participan en la representación del valor. Para los tipos de caracteres sin signo, todos los patrones de bits posibles de la representación del valor representan números. Estos requisitos no son válidos para otros tipos. En cualquier implementación particular, un objeto dechar
simple puede tomar los mismos valores que unsigned char
o ununsigned char
; cuál es definido por la implementación.
El siguiente código compila, pero tiene un comportamiento diferente para el tipo de carácter que para los tipos int.
En particular
cout << getIsTrue< isX<int8>::ikIsX >() << endl;
cout << getIsTrue< isX<uint8>::ikIsX >() << endl;
cout << getIsTrue< isX<char>::ikIsX >() << endl;
da como resultado 3 instancias de plantillas para tres tipos: int8, uint8 y char. ¿Lo que da?
Lo mismo no es cierto para ints: int y uint32 que resultan en la misma creación de instancias de plantilla, y se firman en otro.
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
Mientras que la mayoría de los tipos integrales como short
e int
se signed
defecto, char
no tiene una señalización predeterminada en C ++.
Es un error común que los programadores de C ++ se topan cuando usan char
como un tipo entero de 8 bits.
Para preguntas como esta, me gusta ver el documento de Rationale para C, que a menudo también proporciona respuestas a misterios de C ++, que a veces surgen cuando leo el Estándar. Tiene esto que decir al respecto:
Se especifican tres tipos de caracteres: firmado, simple y sin signo. Un char simple puede representarse como firmado o no, dependiendo de la implementación, como en la práctica anterior. El tipo char firmado se introdujo para poner a disposición un tipo entero con signo de un byte en los sistemas que implementan el carácter simple como sin signo. Por razones de simetría, la palabra clave signed está permitida como parte del nombre de tipo de otros tipos integrales.
eso es correcto, char
, char
unsigned char
y signed char
son tipos separados. Probablemente hubiera sido bueno si char
hubiera sido solo un sinónimo de signed char
o unsigned char
dependiendo de la implementación de tu compilador, pero el estándar dice que son tipos separados.