迭代器如何 map/know 当前位置或元素
How do iterators map/know their current position or element
考虑以下代码示例:
#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; })
ensures/knows 如何知道 i 是迭代器指向的当前元素。
我无法在不使用任何 v.currently_i_am_at_this_posiition()
的情况下弄清楚,迭代是如何完成的。我知道迭代器是什么,但我很难掌握它们。谢谢:)
迭代是通过使用 iterator object
An iterator is any object that, pointing to some element in a range of
elements (such as an array or a container), has the ability to iterate
through the elements of that range using a set of operators (with at
least the increment (++) and dereference (*) operators).
The most obvious form of iterator is a pointer: A pointer can point to
elements in an array, and can iterate through them using the increment
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
}
迭代器在递增时跟踪当前指向的元素,并在取消引用时跟踪它returns当前指向的元素的值。
为了教学和清晰起见,您可能还会想到如下操作(请勿在家中尝试)
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
)。
迭代器是根据指针建模的,确实如此。它们在内部如何工作并不重要,但是 可能的 实现实际上是在内部有一个指向当前元素的指针。
考虑以下代码示例:
#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; })
ensures/knows 如何知道 i 是迭代器指向的当前元素。
我无法在不使用任何 v.currently_i_am_at_this_posiition()
的情况下弄清楚,迭代是如何完成的。我知道迭代器是什么,但我很难掌握它们。谢谢:)
迭代是通过使用 iterator object
An iterator is any object that, pointing to some element in a range of elements (such as an array or a container), has the ability to iterate through the elements of that range using a set of operators (with at least the increment (++) and dereference (*) operators).
The most obvious form of iterator is a pointer: A pointer can point to elements in an array, and can iterate through them using the increment 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
}
迭代器在递增时跟踪当前指向的元素,并在取消引用时跟踪它returns当前指向的元素的值。
为了教学和清晰起见,您可能还会想到如下操作(请勿在家中尝试)
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
)。
迭代器是根据指针建模的,确实如此。它们在内部如何工作并不重要,但是 可能的 实现实际上是在内部有一个指向当前元素的指针。