为什么我不能将反向迭代器转换为前向迭代器?

时间:2010-12-10 10:40:27

标签: c++ iterator

嗯,我知道为什么,这是因为没有转换,但为什么没有转换呢?为什么转发迭代器可以转向反转迭代器而不是反过来呢?更重要的是,如果我想这样做,我该怎么办?是否有一些适配器允许您使用前向迭代器向后迭代?

std::vector<int> buffer(10);
std::vector<int>::iterator forward = buffer.begin();
std::vector<int>::reverse_iterator backward = buffer.rbegin();
++forward;
++backward;
std::vector<int>::iterator forwardFromBackward = std::vector<int>::iterator(backward); // error! Can't convert from reverse_iterator to iterator!
std::vector<int>::reverse_iterator backwardFromForward = std::vector<int>::reverse_iterator(forward); // this is fine

3 个答案:

答案 0 :(得分:17)

你可以写一个辅助函数。 reverse_iterator的一个特点是base()给出了一个前向迭代器,它是反向迭代器取消引用的值的下一个。 This is because a reverse iterator physically points to the element after the one it logically points to。因此,要将前向迭代器放在与reverse_iterator相同的项目上,您需要将base()的结果递减1,您可以先增加反向迭代器 < / em>,然后选择.base()

两个例子如下所示:

#include <iostream>
#include <vector>
#include <iterator>

//result is undefined if passed container.rend()
template <class ReverseIterator>
typename ReverseIterator::iterator_type make_forward(ReverseIterator rit)
{
    return --(rit.base()); // move result of .base() back by one.
    // alternatively
    // return (++rit).base() ;
    // or
    // return (rit+1).base().
}

int main()
{
    std::vector<int> vec(1, 1);
    std::vector<int>::reverse_iterator rit = vec.rbegin();
    std::vector<int>::iterator fit = make_forward(rit);
    std::cout << *fit << ' ' << *rit << '\n';
} 

警告:此行为与reverse_iterator(iterator)构造函数的行为不同。

答案 1 :(得分:2)

两个(反向)迭代器跨越一系列值(例如begin(),end()rbegin(),rend())是很常见的。对于两个反向迭代器rA,rB描述的任何范围,范围rB.base(),rA.base()将在向前方向上跨越相同的范围。

#include <iostream>
#include <iterator>
#include <vector>

int main() {
  std::vector<int> vec{10,11,12,13,14,15};

  // spans the range from 13 to 10
  auto rfirst=std::rbegin(vec)+2;
  auto rlast=std::rend(vec);

  // Loops forward, prints 10 11 12 13
  for(auto it = rlast.base(); it != rfirst.base(); ++it){
    std::cout << *it << " ";
  }
}

如果从概念上讲,您只对单个项目感兴趣(例如find_if的结果),则使用@visitor的make_forward。即使在这种情况下,范围思想也有助于跟踪反向迭代器的有效性:

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

int main() {
  std::vector<int> vec{10,11,12,13,14,15};

  auto rfirst=std::rbegin(vec);
  auto rlast=std::rend(vec);

  auto rfound = std::find_if(rfirst,rlast, [](int v){ return v<13; });

  if(rfound != rlast){
    std::cout << *rfound << " "; // prints 12
    auto forwardFound = make_forward(rfound) ; 
    std::cout << *forwardFound << " "; // prints 12
  }
}

答案 2 :(得分:0)

您可以使用此代码

从反向迭代器中获取迭代器
container.begin() + (reverseIter - container.rbegin() - 1);