字符!=(有符号字符),字符!=(无符号字符)

2022-01-12 00:00:00 char c++

下面的代码可以编译,但 char 类型的行为与 int 类型的行为不同.

The code below compiles, but has different behavior for the char type than for the int types.

特别是

   cout << getIsTrue< isX<int8>::ikIsX  >() << endl;
   cout << getIsTrue< isX<uint8>::ikIsX  >() << endl;
   cout << getIsTrue< isX<char>::ikIsX  >() << endl;

导致三种类型的 3 个模板实例化:int8、uint8 和 char.什么给了?

result in 3 instantiations of templates for three types: int8, uint8 and char. What gives?

int 不一样:int 和 uint32 导致相同的模板实例化,并签署了另一个 int.

The same is not true for ints: int and uint32 which result in the same template instantiation, and signed int another.

原因似乎是 C++ 将 char、signed char 和 unsigned char 视为三种不同的类型.而 int 与带符号的 int 相同.这是对的还是我错过了什么?

The reason seems to be that C++ sees char, signed char and unsigned char as three different types. Whereas int is the same as a signed int. Is this right or am I missing something?

#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;

}

我正在使用 g++ 4.something

I'm using g++ 4.something

推荐答案

这是你从标准中得到的答案:

Here is your answer from the standard:

3.9.1 基本类型 [basic.fundamental]

3.9.1 Fundamental types [basic.fundamental]

声明为字符(char)的对象应足够大以存储实现的基本字符集的任何成员.如果该集合中的字符存储在字符对象中,则该字符对象的整数值等于该字符的单个字符文字形式的值.char 对象是否可以保存负值是实现定义的.字符可以显式声明为 unsignedsigned.Plain charsigned charunsigned char 是三种不同的类型. Achar、一个 signed char 和一个 unsigned char 占用相同的存储量并具有相同的对齐要求(basic.types);也就是说,它们具有相同的对象表示.对于字符类型,对象表示的所有位都参与值表示.对于无符号字符类型,值表示的所有可能的位模式都表示数字.这些要求不适用于其他类型.在任何特定的实现,一个普通的 char 对象可以采用与 signed charunsigned char 相同的值;哪一个是实现定义的.

Objects declared as characters (char) shall be large enough to store any member of the implementation's basic character set. If a character from this set is stored in a character object, the integral value of that character object is equal to the value of the single character literal form of that character. It is implementation-defined whether a char object can hold negative values. Characters can be explicitly declared unsigned or signed. Plain char, signed char, and unsigned char are three distinct types. A char, a signed char, and an unsigned char occupy the same amount of storage and have the same alignment requirements (basic.types); that is, they have the same object representation. For character types, all bits of the object representation participate in the value representation. For unsigned character types, all possible bit patterns of the value representation represent numbers. These requirements do not hold for other types. In any particular implementation, a plain char object can take on either the same values as a signed char or an unsigned char; which one is implementation-defined.

相关文章