在《C++ Primer》书籍的第三章中,有以下用于将向量中的元素重置为零的 for 循环:
for (vector<int>::size_type ix = 0; ix ! = ivec.size(); ++ix)
ivec[ix] = 0;
为什么要使用 vector<int>::size_type ix = 0
?不能直接写成 int ix = 0
吗?使用第一种形式相对于使用第二种形式有何好处?
谢谢。
size_type | 无符号整数类型 | 一种类型,能够表示分配模型中最大对象的大小
然后它补充说:
本国际标准中描述的容器实现可以假设其Allocator模板参数满足以下两个附加要求,超出了表32中的要求。
- typedef成员pointer、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
是无符号整数类型,而 int
不一定是无符号的。 :-)是的,你可以使用int
,但只有类型为vector<int>::size_type
的类型保证其类型可用于索引所有向量元素。
它可能与int
的大小不同。例如,在编译64位Windows时,int
宽度为32位,而vector<int>::size_type
将为64位。
您可以使用std::size_t
代替冗长的vector<int>::size_type
,因为前者是后者的typedef。然而,如果您改变容器类型,则其size_type
可能是不同的类型,如果它使用std::size_t
,则您可能需要修改代码。
int
或 unsigned int
之外的其他类型吗? - Simplicityint
的大小取决于具体的实现。例如,对于 VisualC++,请参见此处:http://msdn.microsoft.com/en-us/library/s3f49ktz(VS.80).aspx。正如您所看到的,`int` 是32位的,但指针是64位的。还可以参考http://blogs.msdn.com/oldnewthing/archive/2005/01/31/363790.aspx。 - Daniel Gehrigervector<int>::size_type
是一种类型,保证可以容纳您可能拥有的最大vector
的大小,因此它保证了您可以索引vector
的所有元素(因为索引从0到大小-1);它是所有vector
方法中用于索引和大小的类型。
如果您有非常大的数组,这可能实际上很重要,因为其他整数类型可能会溢出(如果它们是带符号的类型,事情可能会变得相当奇怪);即使您永远不会获得如此巨大的数组,这基本上也是一种代码清理方式;此外,您的ix
具有与ivec.size()
相同的类型,因此您不会收到比较有符号和无符号整数的警告。
背景:vector<T>::size_type
通常是size_t
的typedef
(我在某个地方读到过实际上标准隐含强制使用它是size_t
- 编辑:根本就不是隐含的,请参见@Nawaz的答案),而sizeof
运算符的返回类型是size_t
。这暗示它可以容纳可用于C++应用程序的最大对象的大小,因此它肯定(仅)足够大,以索引任何类型的数组。
实际上,我也将size_t
(在<cstddef>
中定义)用作C风格数组的索引,并且出于完全相同的原因,我认为这是一个好习惯。
顺便说一句,您还可以完全忘记用于索引的类型,而只需使用迭代器:
for (vector<int>::iterator it = ivec.begin(); it != ivec.end(); ++it)
*it = 0;
或者使用迭代器和 <algorithm>
库:
std::fill(ivec.begin(), ivec.end(), 0);
这两个选项适用于任何容器ivec
,因此如果您决定更改容器类型,则无需更改代码。
使用vector
还可以使用assign
方法(如其他答案中建议的):
ivec.assign(ivec.size(), 0);
size_t
还是 std::size_t
?;-) - fredoverflowusing namespace std;
(但不在我的代码中):P
,std::size_t
。 - Matteo Italiavector<int>::size_type是一种可以确保指定你可能拥有的最大向量大小的类型
时,你能再解释一下吗?谢谢。 - Simplicitysize_type
可以存储您实际可以分配的最大数组大小(=项目数),因此,无论您的数组大小如何,使用size_type
作为索引迭代它时,您可以确信不会出现任何整数溢出问题。 - Matteo Italiaint
,因为vector<int>::size_type
是无符号类型,也就是说,向量将其元素用无符号类型索引。然而,int
是有符号类型,混合使用有符号和无符号类型可能会导致奇怪的问题。(尽管在您的示例中对于较小的n这不会成为问题。)size_t
(而不是T::size_type)更清晰 - 打字更少,应该适用于所有实现。for(size_t ix=0; ix != ivec.size(); ++ix) ...
最好写成:
for(size_t i=0, e=ivec.size(); i!=e; ++ix) ...
for
循环的汇编代码比第二个更紧凑,我会非常惊讶。vector<T>::size()
的调用将被内联。 - Daniel Gehrigerstd::vector
来说,影响向量大小的所有代码对编译器都是可见的,因为编译器必须针对元素类型进行特化。我快速运行了一次测试,事实上并没有差别。 - Daniel Gehrigersom_func
对v
的操作做出任何假设。对v.size()
的调用始终可以作为从存储向量大小的内存位置加载的内联操作来执行。但是,编译器不能像使用OP的优化时那样将其放入寄存器中。 - Daniel Gehriger++i
。 - Daniel Gehriger
int
类型永远不会是无符号的。 - Ayxan Haqverdili