为什么我可以在 MSVS 中使用 size_t 和 std::size_t 而不使用传统的标头?
Why can I use size_t and std::size_t in MSVS without the traditional headers?
我正在使用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++多年前似乎合理的设计向后兼容包含系统所付出的代价。这种限制和缺点在今天是众所周知的,因此委员会正在研究模块,这是当前纳入机制的现代替代方案。
至于为什么可以在没有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
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- 大于65535的C++数组[size]引发不一致的溢出
- 为什么(-1)%vector::size()总是返回0
- 在for循环中使用auto vs decltype(vec.size())来处理字符串的向量
- 循环中的条件:为什么每次都调用strlen(),而vector.size()只调用一次
- 为什么这个 std::queue/指向结构的指针列表直到 List.Size() == 0 才释放内存?
- 在函数中使用 const int size 参数创建数组会在 Visual Studio 中抛出错误 C++:表达式的计
- vector.size() 在比较中意外工作
- vector.back() 和 vector[vector.size() - 1] 之间的区别?
- 返回 str vs. str.substr(0,str.size()) 在 leetcode 中给了我不同的输出
- 为什么 GCC 不能假设 std::vector::size 在这个循环中不会改变?
- 为什么"(!v.empty())"比"(v.size() >0)"好?
- 迭代器库中的 std::size() 不适用于传递给函数的 C 样式数组
- std::string.size() 未知行为
- 为什么gmp会在这里与"invalid next size"重新定位一起崩溃?
- 为什么我会"Invalid read of size 8"?(瓦尔格林德)
- 与传统的多态处理相比,使用 std::variant 有什么优势?
- 从 std::string 到 std::array<char,size> 的 memcopy 额外数据是否是一种未定义的行为?
- 在目录中查找所有.cpp.h文件(include,src等)的传统方法
- 使用 std::size 来自非 const 上下文