下面的代码编译,但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
答案 0 :(得分:58)
以下是您对标准的回答:
3.9.1基本类型[basic.fundamental]
声明为字符(
char
)的对象应足够大,以存储实现的基本字符集的任何成员。如果此组中的字符存储在字符对象中,则该字符对象的整数值等于该字符的单个字符文字形式的值。实现定义了char
对象是否可以保存负值。可以明确声明字符unsigned
或signed
。 普通char
,signed char
和unsigned char
是三种不同的类型。 Achar
,{{1} } {和signed char
占用相同数量的存储空间并具有相同的对齐要求( basic.types );也就是说,它们具有相同的对象表示。对于字符类型,对象表示的所有位都参与值表示。对于无符号字符类型,值表示的所有可能位模式表示数字。这些要求不适用于其他类型。在任何特定的 在实现中,普通unsigned char
对象可以采用与char
或signed char
相同的值;哪一个是实现定义的。
答案 1 :(得分:22)
对于这样的问题,我想查看C的基本原理文档,它通常也提供C ++奥秘的答案,在阅读标准时有时会出现。它有这样的说法:
指定了三种类型的char:signed,plain和unsigned。普通字符可以表示为有符号或无符号,这取决于实现,如在先前实践中那样。引入了类型signed char,以便在将纯字符号作为unsigned实现的系统上提供一个单字节有符号整数类型。出于对称的原因,允许将关键字signed作为其他整数类型的类型名称的一部分。
答案 2 :(得分:21)
虽然short
和int
等大多数整数类型默认为signed
,但char
在C ++中没有默认标志。
当C ++程序员使用char
作为8位整数类型时,这是一个常见的错误。
答案 3 :(得分:14)
这是正确的,char
,unsigned char
和signed char
是不同的类型。如果char
只是signed char
或unsigned char
的同义词,这可能会很好,具体取决于您的编译器实现,但标准说它们是不同的类型。