Afs*_*hin 27 c++ overloading size-t language-lawyer
C++ 标准提到了这一点std::size_t
:
该类型
size_t
是实现定义的无符号整数类型,它足够大以包含任何对象的字节大小 ([expr.sizeof])。
现在我的问题是,这种类型是否与其他 unsigned int 类型不同。我的意思是,我是否应该能够有这样的重载:
void myfunc(std::uint16_t) {}
void myfunc(std::uint32_t) {}
void myfunc(std::uint64_t) {}
void myfunc(std::size_t) {}
Run Code Online (Sandbox Code Playgroud)
因为如果它是一个不同的类型,我应该能够拥有这些重载,而如果不是,我应该得到重新定义错误。我总是认为这std::size_t
应该是一个不同的类型,但我目前收到重新定义错误,这意味着它不是(至少在 GCC 和 Clang 中)
我问这个问题的原因是我想知道我是否对不同的 unsigned int 大小重载了一个函数,我是否可以安全地假设其中一个将被调用std::size_t
或不被调用。
use*_*522 16
现在我的问题是,这种类型是否与其他 unsigned int 类型不同。
您的问题在很大程度上取决于您对“ unsigned int types ”的确切含义。我假设这是指标准定义的“无符号整数类型”。
它不能是与其他无符号整数类型不同的类型。所有无符号整数类型都在[basic.fundamental]/2中专门列出。这些是标准无符号整数类型 unsigned char
、unsigned short
、unsigned int
、unsigned long
和unsigned long long
,以及扩展无符号整数类型(如果实现定义了任何类型)(在最常见的 C++ 实现中通常不是这种情况)。
如果您打算“ unsigned int types ”引用上面列出的标准无符号整数类型,那么答案就变成size_t
既不要求也不禁止成为其中之一,因为它也可能是扩展无符号整数类型之一。但如果实现没有这些,那么它必须是标准无符号整数类型之一。
如果您希望“ unsigned int types ”表示标准中定义的任何也具有无符号符号性的“整数类型” ,那么答案又是它不能与该集合不同,因为该集合仅仅是该集合的超集所有无符号整数类型,添加,,以及可能的和(具有实现定义的符号)。char8_t
char16_t
char32_t
char
wchar_t
(您可以在我上面链接的后 C++20 ISO C++ 草案 N4868 的 [basic.fundamental]/1 到 11 中的标准中找到所有提到的术语的定义。)
因为如果它是一个不同的类型,我应该能够拥有这些重载,而如果不是,我应该得到重新定义错误。
不管上述情况如何,都不能保证会导致重新定义错误,因为虽然类型uint16_t
、uint32_t
和uint64_t
也必须是来自同一类别的无符号整数类型,但它们不必覆盖整个类别,事实上也不能覆盖整个类别,因为有至少 5 个无符号整数类型,但您只列出了三个uintX_t
重载。因此size_t
不需要匹配其中任何一个,事实上根本不需要匹配任何一个uintX_t
。
例如,在 64 位体系结构上,通常uint16_t
是unsigned short
、uint32_t
是unsigned int
和uint64_t
是unsigned long
或unsigned long long
,其余一个不被任何别名uintX_t
。
所以超载设置是不安全的。size_t
可以是其中之一uintX_t
,也可以不是,并且既不是整个uintX_t
集合,也不是整个集合(包括size_t
必须覆盖所有无符号整数类型的集合)。
如果要重载所有无符号整数类型,请按上面列出的标准无符号整数类型的实际(非别名)类型名称以及所有扩展无符号整数类型(如果您的实现有它们)进行重载。但是,请考虑可能受类型特征约束的模板是否不是更好的选择,因为您无法移植地了解扩展整数类型。
C++ 头<cstddef>
实际上与 C 相同<stddef.h>
。
来自 C++17 标准
1 头文件的内容和含义与 C 标准库头文件 <stdlib.h> 相同,只是它没有声明类型 wchar_t,以及 21.2.3、21.2.4、21.5、23.10 中所述的除外。 11、24.5.6、28.8、29.6.9 和 29.9.2。
在 C 中,名称 size_t 被定义为宏
7.19 通用定义<stddef.h>
1 头文件 <stddef.h> 定义以下宏并声明以下类型。有些还在其他标头中定义,如其各自的子条款中所述。2 类型有
ptrdiff_t
Run Code Online (Sandbox Code Playgroud)
这是两个指针相减结果的有符号整数类型;
size_t
Run Code Online (Sandbox Code Playgroud)
这是 sizeof 运算符结果的无符号整数类型;
通常size_t
被定义为类型的别名unsigned long
。
4 用于 size_t 和 ptrdiff_t 的类型的整数转换等级不应大于有符号长整型,除非实现支持足够大的对象以使其必要