迭代std :: vector:无符号与有符号索引变量

在C ++中迭代一个向量的正确方法是什么?

考虑这两个代码片段,这个工作正常:

for (unsigned i=0; i < polygon.size(); i++) {
    sum += polygon[i];
}

和这个:

for (int i=0; i < polygon.size(); i++) {
    sum += polygon[i];
}

它会生成warning: comparison between signed and unsigned integer expressions

我是C ++世界中的新成员,所以unsigned变量对我来说看起来有点可怕,我知道如果使用不正确, unsigned变量可能会很危险,所以 - 这是正确的吗?


向后迭代

看到这个答案。

迭代前进

这几乎是相同的。 只需按增量更改迭代器/交换减量。 你应该更喜欢迭代器。 有些人告诉你使用std::size_t作为索引变量类型。 但是,这不是便携式的。 总是使用容器的size_type typedef(虽然在forward迭代的情况下只能进行转换,但在使用std::size_t情况下,实际上在向后迭代的情况下可能会出错,以防std::size_tsize_type的typedef更宽):

使用std :: vector

使用迭代器

for(std::vector<T>::iterator it = v.begin(); it != v.end(); ++it) {
    /* std::cout << *it; ... */
}

重要的是,对于其定义不了解的迭代器,始终使用前缀增量形式。 这将确保您的代码尽可能通用。

使用Range C ++ 11

for(auto const& value: a) {
     /* std::cout << value; ... */

使用索引

for(std::vector<int>::size_type i = 0; i != v.size(); i++) {
    /* std::cout << someVector[i]; ... */
}

使用数组

使用迭代器

for(element_type* it = a; it != (a + (sizeof a / sizeof *a)); it++) {
    /* std::cout << *it; ... */
}

使用Range C ++ 11

for(auto const& value: a) {
     /* std::cout << value; ... */

使用索引

for(std::size_t i = 0; i != (sizeof a / sizeof *a); i++) {
    /* std::cout << a[i]; ... */
}

尽管如此,请阅读后向迭代回答sizeof方法可以产生的问题。


四年过去了,Google给了我这个答案。 使用标准的C ++ 11(又名C ++ 0x),实际上有一个新的令人愉快的方式(以打破向后兼容性为代价):新的auto关键字。 它可以节省您必须明确指定要使用的迭代器的类型(重复使用向量类型)的痛苦,当(编译器)显而易见时,要使用哪种类型。 用v作为你的vector ,你可以做这样的事情:

for ( auto i = v.begin(); i != v.end(); i++ ) {
    std::cout << *i << std::endl;
}

C ++ 11更进一步,为您提供了一种特殊的语法来迭代像矢量这样的集合。 它消除了编写总是相同的东西的必要性:

for ( auto &i : v ) {
    std::cout << i << std::endl;
}

要在工作程序中查看它,请构建一个文件auto.cpp

#include <vector>
#include <iostream>

int main(void) {
    std::vector<int> v = std::vector<int>();
    v.push_back(17);
    v.push_back(12);
    v.push_back(23);
    v.push_back(42);
    for ( auto &i : v ) {
        std::cout << i << std::endl;
    }
    return 0;
}

在写这篇文章时,当你用g ++编译时,你通常需要通过给出一个额外的标志来设置它与新标准一起工作:

g++ -std=c++0x -o auto auto.cpp

现在你可以运行这个例子:

$ ./auto
17
12
23
42

请注意,关于编译和运行的说明特定于Linux上的gnu c ++编译器,程序应该是平台(和编译器)独立的。


在你的例子中的特定情况下,我会使用STL算法来实现这一点。

#include <numeric> 

sum = std::accumulate( polygon.begin(), polygon.end(), 0 );

对于一个更一般的,但仍然相当简单的情况下,我会去:

#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>

using namespace boost::lambda;
std::for_each( polygon.begin(), polygon.end(), sum += _1 );
链接地址: http://www.djcxy.com/p/78755.html

上一篇: Iteration over std::vector: unsigned vs signed index variable

下一篇: Qt: does "new without delete" cause memory leaks with controls?