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

时间:2009-01-12 18:41:08

标签: c++ char

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

特别是

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

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

对于ints来说也是如此:int和uint32导致相同的模板实例化,并且将int签名为另一个。

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

#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

4 个答案:

答案 0 :(得分:58)

以下是您对标准的回答:

  

3.9.1基本类型[basic.fundamental]

     

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

答案 1 :(得分:22)

对于这样的问题,我想查看C的基本原理文档,它通常也提供C ++奥秘的答案,在阅读标准时有时会出现。它有这样的说法:

  

指定了三种类型的char:signed,plain和unsigned。普通字符可以表示为有符号或无符号,这取决于实现,如在先前实践中那样。引入了类型signed char,以便在将纯字符号作为unsigned实现的系统上提供一个单字节有符号整数类型。出于对称的原因,允许将关键字signed作为其他整数类型的类型名称的一部分。

Rationale for C

答案 2 :(得分:21)

虽然shortint等大多数整数类型默认为signed,但char在C ++中没有默认标志。

当C ++程序员使用char作为8位整数类型时,这是一个常见的错误。

答案 3 :(得分:14)

这是正确的,charunsigned charsigned char是不同的类型。如果char只是signed charunsigned char的同义词,这可能会很好,具体取决于您的编译器实现,但标准说它们是不同的类型。