Der folgende Code wird kompiliert, hat aber für den Zeichenarttyp ein anderes Verhalten als für die int-Typen.char! = (Vorzeichenbehaftetes Zeichen), Zeichen! = (Vorzeichenloses Zeichen)
Insbesondere
cout << getIsTrue< isX<int8>::ikIsX >() << endl;
cout << getIsTrue< isX<uint8>::ikIsX >() << endl;
cout << getIsTrue< isX<char>::ikIsX >() << endl;
Ergebnis in 3 instantiations von Vorlagen für drei Typen: int8, uint8 und char. Was gibt?
Das gleiche gilt nicht für ints: int und uint32, die zu derselben Template-Instanziierung führen, und int int.
Der Grund scheint zu sein, dass C++ char, signed char und unsigned char als drei verschiedene Typen sieht. Während int ist das gleiche wie ein vorzeichenbehafteter Int. Ist das richtig oder fehlt mir etwas?
#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;
}
Ich bin mit g ++ 4.something
Sie sollten auch beachten, dass es keine Garantie dafür gibt, dass 'int8_t' ein' unterzeichnet char' sein wird und 'uint8_t' wird eine' unsigned char' sein. Insbesondere ist auf Solaris 'int8_t' nur' char' wenn 'char' signiert ist. Mit anderen Worten, Ihr Code wird dort nicht kompiliert. –
"int und uint32, die in der gleichen Vorlage Instanziierung führen, und signed int anderen" Dies sollte definitiv anders herum sein, da int signiert ist. –