为什么C++ STL array不同尺寸的迭代器可跨大小赋值并正常运行?
问题解答
现象本质:你观察到的行为是主流STL实现的特定结果,不属于C++标准强制规定的可移植行为
主流STL实现(GCC libstdc++、Clang libc++、MSVC STL)中,非bool特化的std::array<T, N>的迭代器,直接定义为原生指针T*类型。
这就意味着只要元素类型T相同,不管模板参数N的值是多少,std::array<T, N>::iterator都是同一个类型。你代码里array<int, 1>::iterator和array<int,8>::iterator本质都是int*,自然可以互相赋值,排序、遍历逻辑也不会有任何问题。
你尝试将模板尺寸改为183、0甚至负数的情况也能运行,原因也一样:std::array的第二个模板参数要求是无符号整数类型size_t,你传入负数只会触发隐式类型转换为对应的无符号值,不会改变迭代器的int*本质,所以不影响运行。
注意事项:不要在生产代码中使用这种写法
C++标准仅要求std::array的迭代器满足随机访问迭代器的特性,并未强制要求其实现为原生指针。如果遇到将std::array迭代器实现为携带N参数的自定义类的STL实现,不同N的迭代器会被判定为不同类型,你的代码会直接编译失败,可移植性为零。
std::array迭代器的设计逻辑
- 零开销封装要求:
std::array的设计目标是作为原生固定大小数组的安全替代品,运行开销和原生数组完全一致。使用原生指针作为迭代器,可以完全对齐原生数组的指针访问性能,没有额外封装开销。 - 迭代器的职责边界:迭代器的核心作用是标记单个元素的位置、支持元素访问和序列遍历,不需要携带容器的大小信息,容器大小属于容器本身的属性,和迭代器无关。因此相同元素类型、不同大小的
std::array的迭代器本身没有功能差异,设计为同类型是完全合理的。
内容的提问来源于stack exchange,提问作者informatics-mathematics
相关产品推荐
相关产品推荐

