在C++ Primer
一书的第(3)章中,有以下for循环将向量中的元素重置为零。
for (vector<int>::size_type ix = 0; ix ! = ivec.size(); ++ix)
ivec[ix] = 0;
为什么使用vector<int>::size_type ix = 0
?我们不能说int ix = 0
吗?在第二个表格中使用第一个表格有什么好处?
感谢。
答案 0 :(得分:16)
C ++标准说,
size_type | unsigned integral type | a type that can represent the size of the largest object in the allocation model
然后它补充说,
容器的实现 在这个国际描述 标准允许假设 他们的Allocator模板参数 满足以下两个额外的 要求超出表32中的要求。
- typedef成员指针,const_pointer,size_type和 difference_type是 需要分别为T *,T const *,size_t和ptrdiff_t
所以最有可能的是,size_type
是size_t
的typedef。
标准确实将其定义为,
template <class T>
class allocator
{
public:
typedef size_t size_type;
//.......
};
因此,最重要的要点是:
size_type
是unsigned
积分,而int
不 必然 unsigned
。 : - )答案 1 :(得分:12)
是的,您可以使用int
,但只有类型vector<int>::size_type
保证其类型可用于索引所有向量元素。
它可能与int
的大小相同,也可能不同。例如,在为64位Windows编译时,int
为32位宽,而vector<int>::size_type
为64位宽。
您可以使用vector<int>::size_type
,而不是使用相当冗长的std::size_t
,因为前者是后者的typedef。但是,如果您碰巧更改了容器类型,那么其size_type
可能是另一种类型,如果代码使用std::size_t
,则可能需要修改代码。
答案 2 :(得分:9)
vector<int>::size_type
是一种类型,保证保持您可能拥有的最大vector
的大小,因此可以保证让您索引vector
的所有元素(因为索引从0变为size-1);它是所有vector
方法中用于索引和大小的类型。
如果你有非常大的数组,这可能实际上是相关的,因为其他整数类型可能会溢出(如果它们是signed
类型,事情会变得非常奇怪);即使你不会得到这么大的阵列,这可能很重要,它从根本上说是代码清洁的事情;此外,您的ix
具有相同类型的ivec.size()
,因此您不会收到有关比较有符号和无符号整数的警告。
背景:vector<T>::size_type
typedef
通常是size_t
(我在某处读到实际标准的隐式强加给它是size_t
- 编辑:它根本不是隐含的,请参阅 @Nawaz 的答案),而这又是{{的返回类型1}}运算符。这隐含地说它可以保存C ++应用程序中可用的最大对象的大小,所以它肯定(只是)大到足以索引任何类型的数组。
实际上,我使用sizeof
(在size_t
中定义)作为C风格数组的索引,我认为这是一个很好的做法,原因完全相同。
顺便说一句,您可能也会忘记用于索引的类型,只需要使用迭代器:
<cstddef>
或使用迭代器+ for (vector<int>::iterator it = ivec.begin(); it != ivec.end(); ++it)
*it = 0;
:
<algorithm>
这两个选项适用于任何容器std::fill(ivec.begin(), ivec.end(), 0);
,因此如果您决定更改容器类型,则不必更改代码中的任何内容。
使用ivec
,您还可以使用vector
方法(如其他答案所示):
assign
答案 3 :(得分:3)
您不应该使用int
因为vector<int>::size_type
是无符号类型,即向量使用无符号类型对其元素进行索引。 int
但是是签名类型,混合有符号和无符号类型可能会导致奇怪的问题。 (虽然在你的例子中对小n来说不会有问题。)
请注意,我认为使用size_t
(而不是T :: size_type)更清楚 - 减少输入并且应该适用于所有实现。
另请注意您发布的for循环:
for(size_t ix=0; ix != ivec.size(); ++ix) ...
最好写成:
for(size_t i=0, e=ivec.size(); i!=e; ++ix) ...
- 无需每次迭代调用size()。