char!=(signed char), char!=(unsigned char)
Le code ci-dessous compile, mais a un comportement différent pour le type char que pour les types int.
En particulier
cout << getIsTrue< isX<int8>::ikIsX >() << endl;
cout << getIsTrue< isX<uint8>::ikIsX >() << endl;
cout << getIsTrue< isX<char>::ikIsX >() << endl;
résultat dans 3 instanciations de modèles pour trois types: int8, uint8 et char. Ce qui donne?
La même chose n'est pas vraie pour les entiers: int et uint32 qui aboutissent à la même instanciation du modèle, et signé int l'autre.
La raison semble être que C++ voit char, signed char et unsigned char que trois types différents. Alors que l'int est la même que la signature d'un int. Est-ce vrai ou ai-je raté quelque chose?
#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;
}
J'utilise g++ 4.quelque chose
- Vous devriez noter également qu'il n'y a aucune garantie que
int8_t
va être unsigned char
etuint8_t
va être ununsigned char
. En particulier, sur Solarisint8_t
est justechar
sichar
est signé. En d'autres termes, votre code ne parviennent pas à compiler là. - "int et uint32 qui aboutissent à la même instanciation du modèle, et signé int un autre" ce qui devrait certainement être dans l'autre sens que int est signé.
Vous devez vous connecter pour publier un commentaire.
Voici votre réponse à partir de la norme:
Pour des questions telles que la présente, je tiens à examiner la Justification de document pour C, ce qui donne souvent des réponses à C++ mystères ainsi, qui surviennent parfois pour moi lors de la lecture de la Norme. Il a ceci à dire à ce sujet:
Justification de la C
signed char
? Juste afin de l'utiliser pour représenter un octet entier signé?char
pourrait être signée, ou peut-être non signé, qui est définie par l'implémentation, maissigned char
est toujours signé, etunsigned char
est toujours pas signé, si vous voulez être sûr/explicite du typeAlors que la plupart des types intégraux comme
short
etint
défaut d'êtresigned
,char
ne dispose pas d'un défaut de signalisation en C++.C'est une erreur commune que les programmeurs en C++ exécuter lorsqu'ils utilisent
char
comme un 8 bits type entier.c'est correct,
char
,unsigned char
etsigned char
sont des types distincts. Il aurait probablement été bien sichar
était juste un synonyme poursigned char
ouunsigned char
selon vos compilateurs de mise en œuvre, mais la norme dit qu'ils sont les types distincts.