为什么我可以在 MSVS 中使用 size_t 和 std::size_t 而不使用传统的标头?

Why can I use size_t and std::size_t in MSVS without the traditional headers?

本文关键字:size 传统 我可以 MSVS 为什么 std      更新时间:2023-10-16

我正在使用Visual Studio 2017社区版。它允许我在没有适当包含的情况下同时使用size_tstd::size_t。它似乎适用于大多数标准数据库。我认为这是因为库本身的某些部分使用它。例如,我发现导致这种行为的一个例子vector

#include <vector>
#include <iostream>
int main()
{
size_t a = 42;
std::size_t b = 0;
std::cout << a << b;
std::cin.ignore();
}

据推测,这是因为size()函数返回一个std::size_t。这只是一个标头依赖项,我可以通过适当的包含来避免它吗?这仍然不能解释为什么我可以使用命名空间范围调用它。

(我没有使用using namespace std

这个问题意味着并非 std 库中的所有标头都应该具有定义。

严格来说,你的代码是非法的。需要在以下标头中声明size_t类型:

<cstddef>
<cstdio>
<cstdlib>
<cstring>
<ctime>
<cwchar>

但该标准也允许标准标头包含其他标准标头。因此,MSVC 使用的标准库中的标头<vector>很可能包含上述标头之一。这是允许的,但不是标准强制要求的,因此这将适用于您的设置,但可能无法在其他标准库实现上工作,即使在您正在使用的同一版本的未来版本上也是如此。

因此,总而言之,尝试包含标准对您正在使用的所有定义所需的所有标头。

恕我直言,这是一种错误的行为,但这是C++多年前似乎合理的设计向后兼容包含系统所付出的代价。这种限制和缺点在今天是众所周知的,因此委员会正在研究模块,这是当前纳入机制的现代替代方案。


至于为什么可以在没有std::的情况下使用size_t

<cstddef>需要声明std::size_t,也可以选择在全球范围内声明(或引入声明)size_t

<stddef.h>是一个向后兼容的C标头,它在全局范围内声明size_t

因此,要么<cstddef>在全球范围内声明size_t并被<vector>包括在内,要么<stddef.h><vector>包括在内——很可能是通过<cstddef>间接包含的。

https://stackoverflow.com/a/283023/2805305