简体   繁体   English

char!=(signed char), char!=(unsigned char)

[英]char!=(signed char), char!=(unsigned char)

The code below compiles, but has different behavior for the char type than for the int types.下面的代码可以编译,但 char 类型的行为与 int 类型的行为不同。

In particular特别是

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

result in 3 instantiations of templates for three types: int8, uint8 and char.导致三种类型的模板的 3 个实例化:int8、uint8 和 char。 What gives?是什么赋予了?

The same is not true for ints: int and uint32 which result in the same template instantiation, and signed int another.对于 ints 来说情况并非如此:int 和 uint32 导致相同的模板实例化,并签名 int 另一个。

The reason seems to be that C++ sees char, signed char and unsigned char as three different types.原因似乎是 C++ 将 char、signed char 和 unsigned char 视为三种不同的类型。 Whereas int is the same as a signed int.而 int 与有符号 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;

}

I'm using g++ 4.something我正在使用 g++ 4.something

Here is your answer from the standard:这是您从标准中得到的答案:

3.9.1 Fundamental types [basic.fundamental] 3.9.1 基本类型[basic.fundamental]

Objects declared as characters ( char ) shall be large enough to store any member of the implementation's basic character set.声明为字符 ( char ) 的对象应足够大以存储实现的基本字符集的任何成员。 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. char对象是否可以包含负值是实现定义的。 Characters can be explicitly declared unsigned or signed .字符可以显式声明为unsignedsigned Plain char , signed char , and unsigned char are three distinct types.普通char 、有signed charunsigned char是三种不同的类型。 A char , a signed char , and an unsigned char occupy the same amount of storage and have the same alignment requirements ( basic.types ); charsigned charunsigned char占用相同的存储量并具有相同的对齐要求( 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 ;在任何特定的实现中,普通char对象可以采用与有signed charunsigned char相同的值; which one is implementation-defined.哪个是实现定义的。

While most integral types like short and int default to being signed , char does not have a default signage in C++.虽然像shortint这样的大多数整数类型默认为signed ,但char在 C++ 中没有默认标志。

It is neither the type signed char nor unsigned char , so implementations may decide whether it is signed.它既不是signed char类型也不是unsigned char类型,因此实现可以决定它是否有符号。

It's a common mistake that C++ programmers run into when they use char as an 8 bit integer type.这是 C++ 程序员在使用char作为 8 位整数类型时遇到的常见错误。

For questions such as this, i like to look into the Rationale document for C, which often provides answers to C++ mysteries as well, that sometimes arise for me when reading the Standard.对于诸如此类的问题,我喜欢查看 C 的基本原理文档,该文档通常也提供了 C++ 之谜的答案,这些谜团有时会在我阅读标准时出现。 It has this to say about it:它有这样的说法:

Three types of char are specified: signed, plain, and unsigned.指定了三种类型的字符:有符号、普通和无符号。 A plain char may be represented as either signed or unsigned, depending upon the implementation, as in prior practice.一个普通的 char 可以表示为有符号或无符号,这取决于实现,就像在先前的实践中一样。 The type signed char was introduced to make available a one-byte signed integer type on those systems which implement plain char as unsigned.引入了类型有符号字符是为了在那些将纯字符实现为无符号的系统上提供一字节有符号整数类型。 For reasons of symmetry, the keyword signed is allowed as part of the type name of other integral types.出于对称的原因,允许关键字 signed 作为其他整数类型的类型名称的一部分。

Rationale for C C 的基本原理

that's correct, char , unsigned char and signed char are separate types.没错, charunsigned charsigned char是不同的类型。 It probably would have been nice if char was just a synonym for either signed char or unsigned char depending on your compilers implementation, but the standard says they are separate types.如果根据您的编译器实现, char只是有signed charunsigned char的同义词,那可能会很好,但标准说它们是单独的类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM