反向迭代器寻址调整背后的直觉

问题描述 投票:0回答:1

尝试培养一种通过前向和后向迭代器使用索引寻址向量元素的直觉。因为,例如根据 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, ", "));

我的问题是,由于这些寻址方式(范围、元素、受元素限制的范围)有时会一起使用,那么当我们必须调整向后迭代器以及何时不需要调整向后迭代器时,培养直觉的最佳方法是什么?

我可以每次都仔细检查自己和代码,但也许有某种好的经验法则可以帮助了解何时调整、何时不调整?

c++ stl
1个回答
0
投票

成对的迭代器表示半开范围。第一个迭代器是可解引用的,直到它等于第二个迭代器。

如果您需要将迭代器传递给您想要的元素

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));
© www.soinside.com 2019 - 2024. All rights reserved.