我正在使用 Visual Studio 2017 社区版。它允许我同时使用
size_t
和 std::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++ 为了向后兼容包含系统而付出的必要代价,而包含系统在多年前似乎是一个合理的设计。其局限性和缺点如今已众所周知,因此委员会正在开发模块,这是当前包容机制的现代替代方案。
至于为什么可以用
size_t
而不用std::
:
<cstddef>
需要声明 std::size_t
,也可以选择在全局范围内声明(或引入)size_t
。
<stddef.h>
是一个 C
向后兼容的标头,它在全局范围内声明 size_t
。
因此,要么
<cstddef>
在全局级别声明 size_t
并被 <vector>
包含,要么 <stddef.h>
被 <vector>
包含 - 最有可能通过 <cstddef>
间接包含。