尝试培养一种通过前向和后向迭代器使用索引寻址向量元素的直觉。因为,例如根据 en.cppreference.com,
“对于从迭代器 i 构造的反向迭代器 r,关系 &r == &(i - 1) 始终为 true”
很明显我必须通过从生成的向后迭代器中减去一来补偿这一点:
std::vector i1{ 0,1,2,3,4 };
const int element_offset=3;
auto it_forward = i1.begin()+element_offset;
auto it_backward = std::make_reverse_iterator(it_forward)-1;
std::cout << std::endl << "*(it_forward) = " << *(it_forward);
std::cout << std::endl << "*(it_backward) = " << *(it_backward);
更准确地说,最好使用:
auto it_backward = std::prev(std::make_reverse_iterator(it_forward));
同时,当我们反转范围时,这对程序员来说是透明的,我们不需要调整迭代器,我明白为什么。
std::copy(std::make_reverse_iterator(i1.end()),
std::make_reverse_iterator(i1.begin()),
std::ostream_iterator<int>(std::cout, ", "));
我的问题是,由于这些寻址方式(范围、元素、受元素限制的范围)有时会一起使用,那么当我们必须调整向后迭代器以及何时不需要调整向后迭代器时,培养直觉的最佳方法是什么?
我可以每次都仔细检查自己和代码,但也许有某种好的经验法则可以帮助了解何时调整、何时不调整?
成对的迭代器表示半开范围。第一个迭代器是可解引用的,直到它等于第二个迭代器。
如果您需要将迭代器传递给您想要的元素
std::reverse_iterator
,那么您不能使用 end
作为开始,也不能使用空范围的 begin
。此外,没有与反转范围的末尾相对应的迭代器值。
您应该避免考虑的是为特定元素构造一个
reverse_iterator
,而是构造反向迭代器的 pairs 来表示您想要的元素的 range,交换开始和结束。 IE。而不是你的例子
auto it_forward = i1.begin()+element_offset;
auto it_backward = std::make_reverse_iterator(it_forward)-1;
你会有
auto it_forward_begin = i1.begin()+element_offset;
auto it_forward_end = i1.begin()+element_offset+1;
auto it_backward_begin = std::make_reverse_iterator(it_forward_end);
auto it_backward_end = std::make_reverse_iterator(it_forward_begin);
现在您可以简化它,内联结束迭代器
auto it_backward = std::make_reverse_iterator(it_forward+1);
或
auto it_backward = std::make_reverse_iterator(std::next(it_forward));