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 un signed char et uint8_t va être un unsigned char. En particulier, sur Solaris int8_t est juste char si char 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é.
InformationsquelleAutor user48956 | 2009-01-12