[英]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 achar
object can hold negative values.char
对象是否可以包含负值是实现定义的。 Characters can be explicitly declaredunsigned
orsigned
.字符可以显式声明为unsigned
或signed
。 Plainchar
,signed char
, andunsigned char
are three distinct types.普通char
、有signed char
和unsigned char
是三种不同的类型。 Achar
, asigned char
, and anunsigned char
occupy the same amount of storage and have the same alignment requirements ( basic.types );char
、signed char
和unsigned 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 plainchar
object can take on either the same values as asigned char
or anunsigned char
;在任何特定的实现中,普通char
对象可以采用与有signed char
或unsigned 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++.虽然像short
和int
这样的大多数整数类型默认为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 作为其他整数类型的类型名称的一部分。
that's correct, char
, unsigned char
and signed char
are separate types.没错, char
、 unsigned char
和signed 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 char
或unsigned char
的同义词,那可能会很好,但标准说它们是单独的类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.