`size_t` 是否始终是 `vector<int>::size_type` 或任何其他容器类型的别名?

Is `size_t` always an alias for `vector<int>::size_type` or any other container type?

让我们举一个最简单的例子:

公式 1:

std::vector<int> vec;
// add 10E11 elements
for(std::size_t n = 0; n < vec.size(); ++n)
    // ...

公式2:

std::vector<int> vec;
// add 10E11 elements
for(std::vector<int>::size_type n = 0; n < vec.size(); ++n)
    // ...

当然,unsigned int 或任何不合适的数据类型在这里都不起作用,我们必须编译 x64。我的问题是:在任何情况下第一个表述会导致问题,或者我们可以安全地总是用这种更短的表示法来写它吗?如果它们很容易覆盖(x86、任何其他容器、size_type 的其他应用程序),我也会对类似的设置感兴趣。

虽然 std::vector::size_type 通常是 std::size_t,但不能保证一定是。使用

更安全
for(std::vector<int>::size_type n = 0; n < vec.size(); ++n)

尽管所有常见的实现都是如此,但标准对此不作任何保证。保证的是 std::vector<T>::size_type 是一个实现定义的无符号整数类型。

参考文献:

23.2.1 一般容器要求 [container.requirements.general]

X::size_type [is a] unsigned integer type

和 23.3.6.1 Class 模板向量概述 [vector.overview] §2

typedef implementation-defined size_type; // see 23.2

std::vector 保证指针是其整个序列的有效迭代器,因为 vector::data returns "A pointer such that [data(), data() + size()) is a valid range." 那是指针加法,它是在 std::ptrdiff_t 上定义的,这是 std::size_t.

的签名版本

此外,[iterator.requirements.general]/6 适用:

… for integral values n and dereferenceable iterator values a and (a + n), *(a + n) is equivalent to *(addressof(*a) + n)

vector::size_type 可能 std::size_t 更窄 ,例如 64 位系统上的 32 位。但这不是我担心的事情。