以下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_t
是unsigned
为什么重载不一致?
答案 0 :(得分:9)
char
是所有不同的类型,可以重载
[basic.fundamental] / 1
[...]普通
char
,signed char
和unsigned char
是三种不同的类型, 统称为狭义字符类型。 [...]
wchar_t
也是一种独特的类型,但不能使用signed
或unsigned
限定,只能与标准整数类型一起使用。
[dcl.type] / 2
作为一般规则,最多允许一个类型说明符 声明的完整 decl-specifier-seq 或在 type-specifier-seq 或 trailing-type-specifier-seq 。唯一的例外 遵守此规则如下:
[...]
signed
或unsigned
可与char
,long
,short
或int
结合使用。
[dcl.type.simple] / 2
[...]表9总结了 simple-type-specifiers 的有效组合及其指定的类型。
wchar_t
的签名是实施定义:
[basic.fundamental] / 5
[...]类型
wchar_t
应具有相同的大小,签名和对齐方式 要求(3.11)作为其他整体类型之一,称为其 基础类型。
答案 1 :(得分:4)
char
是signed char
和unsigned char
的独特类型。 wchar_t
是另一种不同的类型(用于类型标识),但它具有与其他整数类型完全相同的属性(大小,符号和对齐)。
来自ISO 14882:2003,3.9.1:
普通
char
,signed char
和unsigned char
是三种不同的类型。(...)
类型
wchar_t
是一种不同的类型,其值可以表示不同 指定的最大扩展字符集的所有成员的代码 在受支持的语言环境中(22.1.1)。类型wchar_t
应具有相同的 尺寸,签名和对齐要求(3.9)作为另一个要求 整数类型,称为其基础类型。
没有signed wchar_t
或unsigned wchar_t
这样的事情。文档中的任何地方都没有提到它。
答案 2 :(得分:4)
char
是一种基本类型。 wchar_t
首先演变为库解决方案(在C中),然后成为内置类型,其基础类型,对应于之前用于typedef
它的类型:
“类型
wchar_t
应具有相同的内容 大小,符号和对齐要求(3.11)作为其他整数类型之一,称为底层 输入的
这解释了为什么您无法更改wchar_t
的签名,但这并不能解释为什么char
类型具有未指定的签名。
此外,由于多种原因,大多数编译器默认选择签名的char
是不切实际的。一个原因是负值很烦人,并且通常必须转换为无符号以便比较它们。另一个原因是C字符分类函数需要非负值(传递EOF
时除外)。第三个原因是,在旧的幅度和符号或一个补充机器上,有一个不可用的值。
在Stroustrup的“C ++的设计和演变”中可能有一些解释,但我对此表示怀疑。
这听起来像冻结历史,这在某种程度上对于当时的技术有一定的意义。