迭代器如何映射/知道它们的当前位置或元素

时间:2015-05-26 07:36:54

标签: c++ for-loop iterator

请考虑以下代码示例:

#include <vector>
#include <numeric>
#include <algorithm>
#include <iterator>
#include <iostream>
#include <functional>

int main()
{
    std::vector<int> v(10, 2);
    std::partial_sum(v.cbegin(), v.cend(), v.begin());
    std::cout << "Among the numbers: ";
    std::copy(v.cbegin(), v.cend(), std::ostream_iterator<int>(std::cout, " "));
    std::cout << '\n';

    if (std::all_of(v.cbegin(), v.cend(), [](int i){ return i % 2 == 0; })) {
        std::cout << "All numbers are even\n";
    }
    if (std::none_of(v.cbegin(), v.cend(), std::bind(std::modulus<int>(), 
                                                     std::placeholders::_1, 2))) {
        std::cout << "None of them are odd\n";
    }
    struct DivisibleBy
    {
        const int d;
        DivisibleBy(int n) : d(n) {}
        bool operator()(int n) const { return n % d == 0; }
    };

    if (std::any_of(v.cbegin(), v.cend(), DivisibleBy(7))) {
        std::cout << "At least one number is divisible by 7\n";
    }
}

如果我们看一下代码的这一部分:

if (std::all_of(v.cbegin(), v.cend(), [](int i){ return i % 2 == 0; })) {
            std::cout << "All numbers are even\n";
        }

这很容易理解。它遍历这些向量元素,并找出i%2==0,它们是否完全可被2整除,因此发现它们是偶数还是非。

它的for循环对应物可能是这样的:

for(int i = 0; i<v.size();++i){
    if(v[i] % 2 == 0) areEven = true;    //just for readablity
    else areEven = false;
}

在这个for循环示例中,很清楚我们正在处理的当前元素是i,因为我们实际上正在访问v[i]。但是如何使用相同代码的迭代器版本,它映射i或知道我们当前访问的元素是什么?

[](int i){ return i % 2 == 0; })如何确保/知道我是迭代器指向的当前元素。

我没有使用任何v.currently_i_am_at_this_posiition()就无法解决这个问题,如何进行迭代。我知道迭代器是什么,但我很难抓住它们。谢谢:))

2 个答案:

答案 0 :(得分:5)

迭代器以指针为模型,这就是它。它们如何在内部工作是没有意义的,但可能的实现实际上有一个指向当前元素的指针。

答案 1 :(得分:3)

使用iterator object

完成迭代
  

迭代器是指向某个范围内的某个元素的任何对象   元素(如数组或容器)具有迭代的能力   使用一组运算符通过该范围的元素(使用at   至少增量(++)和解除引用(*)运算符。)

     

最明显的迭代器形式是指针:指针可以指向   数组中的元素,可以使用增量迭代它们   operator(++)。

并通过元素集推进它。代码中的std::all_of函数大致等同于以下代码

template< class InputIt, class UnaryPredicate >
bool c_all_of(InputIt first, InputIt last, UnaryPredicate p)
{
    for (; first != last; ++first) {
        if (!p(*first)) {
            return false; // Found an odd element!
        }
    }
    return true; // All elements are even
}

迭代器在递增时跟踪当前指向的元素,当取消引用时,它返回当前指向的元素的值。

为了教学和清晰起见,你可能还会想到如下操作(不要在家里试试)

bool c_all_of(int* firstElement, size_t numberOfElements, std::function<bool(int)> evenTest)
{
    for (size_t i = 0; i < numberOfElements; ++i)
        if (!evenTest(*(firstElement + i)))
            return false;
    return true;
}

请注意,迭代器是一个强大的抽象,因为它们允许在不同的容器中访问一致的元素(例如std::map)。