为什么char既没有签名也没有签名,但wchar_t是?

时间:2015-09-30 01:49:11

标签: c++ implicit-conversion overloading wchar-t

以下C ++程序编译时没有错误:

void f(char){}
void f(signed char){}
void f(unsigned char){}
int main(){}  

同一程序的wchar_t版本不会:

void f(wchar_t){}
void f(signed wchar_t){}
void f(unsigned wchar_t){}
int main(){}

错误:重新定义'void f(wchar_t)' void f(签名wchar_t){}

似乎wchar_tunsigned 为什么重载不一致?

3 个答案:

答案 0 :(得分:9)

char是所有不同的类型,可以重载

[basic.fundamental] / 1

  

[...]普通charsigned charunsigned char是三种不同的类型,   统称为狭义字符类型。 [...]

wchar_t也是一种独特的类型,但不能使用signedunsigned限定,只能与标准整数类型一起使用。

[dcl.type] / 2

  

作为一般规则,最多允许一个类型说明符   声明的完整 decl-specifier-seq 或在    type-specifier-seq trailing-type-specifier-seq 。唯一的例外   遵守此规则如下:

     

[...]

     

signedunsigned可与charlongshortint结合使用。

[dcl.type.simple] / 2

  

[...]表9总结了 simple-type-specifiers 的有效组合及其指定的类型。

enter image description here

wchar_t的签名是实施定义:

[basic.fundamental] / 5

  

[...]类型wchar_t应具有相同的大小,签名和对齐方式   要求(3.11)作为其他整体类型之一,称为其   基础类型。

答案 1 :(得分:4)

charsigned charunsigned char的独特类型。 wchar_t是另一种不同的类型(用于类型标识),但它具有与其他整数类型完全相同的属性(大小,符号和对齐)。

来自ISO 14882:2003,3.9.1:

  

普通charsigned charunsigned char是三种不同的类型。

     

(...)

     

类型wchar_t是一种不同的类型,其值可以表示不同   指定的最大扩展字符集的所有成员的代码   在受支持的语言环境中(22.1.1)。类型wchar_t应具有相同的   尺寸,签名和对齐要求(3.9)作为另一个要求   整数类型,称为其基础类型。

没有signed wchar_tunsigned wchar_t这样的事情。文档中的任何地方都没有提到它。

答案 2 :(得分:4)

char是一种基本类型。 wchar_t首先演变为库解决方案(在C中),然后成为内置类型,其基础类型,对应于之前用于typedef它的类型:

C ++ 11 $ 3.9.1 / 5
  

类型wchar_t应具有相同的内容   大小,符号和对齐要求(3.11)作为其他整数类型之一,称为底层   输入

这解释了为什么您无法更改wchar_t的签名,但这并不能解释为什么char类型具有未指定的签名。

此外,由于多种原因,大多数编译器默认选择签名的char是不切实际的。一个原因是负值很烦人,并且通常必须转换为无符号以便比较它们。另一个原因是C字符分类函数需要非负值(传递EOF时除外)。第三个原因是,在旧的幅度和符号或一个补充机器上,有一个不可用的值。

在Stroustrup的“C ++的设计和演变”中可能有一些解释,但我对此表示怀疑。

这听起来像冻结历史,这在某种程度上对于当时的技术有一定的意义。