何时应该使用 vector<int>::size_type 而不是 size_t?

8
这个问题中,我看到以下内容:
for (vector<int>::size_type ix = 0; ix ! = ivec.size(); ++ix) {
    ivec[ix] = 0;
}

我明白为什么这里没有使用 int,但为什么不直接使用 size_t

在什么情况下我应该使用 vector<int>::size_type 而不是 size_t


2
当您在迭代向量时。(在这种情况下。) - user529758
3
当你想要卖弄学问时。 - David Brown
这更加明确。并不是每个人都知道它们实际上是相同的。 - chris
如果可以避免的话,不要自己编写循环。在这里正确的做法是编写std :: fill(ivec.begin(),ivec.end(),0); - user515430
4个回答

18
使用size_type的主要时机是在模板中。虽然std::vector<T>::size_type通常是size_t,但some_other_container<T>::size_type可能会是其他类型1。用户被允许添加到std命名空间中的少数内容之一是为某个用户定义的类型专门化现有模板。因此,对于一些奇怪的Tstd::vector<T>::size_type实际上可能是除size_t之外的某种类型,尽管标准库中定义的基本模板可能总是使用size_t

因此,如果您想在与该容器一起工作的模板中使用正确的类型,则应使用container::size_type而不是仅假定size_t

但请注意,通用代码应该很少直接使用容器。相反,它通常应该使用迭代器,因此,它通常会使用类似于std::iterator_traits<WhateverIterator>::difference_type而不是container<T>::size_type


  1. 对于一些特定的Tvector<T>::size_type也可能是不同的类型 - 您被允许放入std命名空间中的少数内容之一是为用户定义的类型现有类的专门化,因此对于一些Tvector<T>可以使用与大多数其他类型完全不同的容器。这对于vector<bool>很典型,但对其他类型也是可能的。

1
有哪些广泛使用的容器,其中 size_type 不是 size_t 的示例? - xdavidliu

8
使用container_type::size_type的一个原因是保持一致性。虽然size_t足以用于索引/计数std::vector,但从概念上讲,它不足以用于索引/计数std::list或任何其他非基于数组的容器。因此,在使用容器时,你应该通常使用container_type::size_type
在通用代码中,当容器的实际类型未知时,你别无选择,只能使用container_type::size_type。即使在特定代码中,当容器已知为std::vector时,也没有必要例外并突然切换到size_t

“对于std::list或任何其他非基于数组的容器进行索引/计数在概念上是不充分的。” 这很有趣,但我想知道为什么?原因是什么? - Nawaz
6
size_t能够容纳最大连续对象的大小,因此对于数组来说总是足够的。然而,并不能保证size_t足够大以容纳整个可用内存的大小。如果容器不要求是连续的,它可能会包含比size_t可以数清的更多小元素。一个经典的例子是旧的分段内存平台,如DOS或Win16。它们的标准内存模型中的size_t只有16位宽,而可用的内存空间远大于64K。 - AnT stands with Russia
2
在具有这种内存模型的分段平台上,您无法拥有大于64K的数组,但可以轻松拥有超过64K个元素的列表。应该足够大以计数任何内容的整数类型实际上是uintptr_t,而不是size_t - AnT stands with Russia
1
@Nawaz:这正是我得出结论的方式。语言并不保证您可以声明一个与整个内存一样大的对象。(再次说明,在标准DOS内存模型中,不允许声明大于64K的数组或结构体,而总内存量远远超过64K)。任何现代的64位实现都可以通过限制对象大小(例如4G)并使用32位的size_t来符合规范。这样的实现仍然可以符合规范。 - AnT stands with Russia
1
仍然存在使用分段内存模型的平台。据我所知,一些IBM大型机使用128位内存,分为64位段,最大对象大小限制在64位边界处。 “size_t”是一个64位类型,但您可以创建一个具有超过“2 ^ 64”个元素的列表。 - AnT stands with Russia
显示剩余3条评论

2

来源:C++中的vector<int>::size_type

"size_type是类型vector<int>的(静态)成员类型。通常,它是std::size_ttypedef,而std::size_t本身通常是unsigned intunsigned long longtypedef。"


这并没有回答问题,因为这只是意味着通常它们是相同的。什么时候是通常?我什么时候需要关心优先选择其中之一? - xdavidliu

-2

我认为它们是相同的。

typedef typename Allocator::size_type size_type;

你的谬论是个人经验的证据。 - sehe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接