【问题标题】:In C++, how to iterate array in reverse using for_each?在 C++ 中,如何使用 for_each 反向迭代数组?
【发布时间】:2013-09-01 20:07:31
【问题描述】:

在 C++11 中,使用 lambda/for_each,我们如何从 end 迭代数组?

我尝试了以下方法,但都导致无限循环:

for_each (end(A), begin(A), [](int i) {
   ....
});

for_each (A.rend(), A.rbegin(), [](int i) {
    ...
});

有什么想法吗?谢谢。

【问题讨论】:

  • 你颠倒了rend和rbegin。
  • @Borgleader 是的,你是对的。谢谢。

标签: c++11 stl stdarray


【解决方案1】:

你错过了吗?

翻转你的rbegin & rend

for_each (A.rbegin(), A.rend(), [](int i) {
    ...
});

增加反向迭代器将它们移向容器的开头

【讨论】:

  • 糟糕,我的错误!非常感谢!
【解决方案2】:

std::for_each( A.rbegin(), A.rend(), [](int i) { /*code*/ } ); 是简单的解决方案。

我写了backwards,它接受一个序列,使用免费的beginend函数从中提取beginend迭代器(使用std::beginstd::endusing附近的声明——完整的 ADL),围绕它们创建反向迭代器,然后返回带有这两个反向迭代器的序列。

这有点简洁,因为你会得到这样的语法:

for( int i : backwards(A) ) {
  // code
}

我发现它比 std::for_each 或手动 for 循环更容易阅读。

但我有点疯了。

这是一个最小的backwards。完整的解决方案可以更好地处理 adl 和一些极端情况。

template<class It, class C>
struct range_for_t{
  It b,e;
  C c; // for lifetime
  It begin()const{return b;}
  It end()const{return e;}
}
template<class It, class C>
range_for_t<It,C> range_for(It b,It e,C&& c){
  return {std::move(b),std::move(e),std::forward<C>(c)};
}

template<class It>
range_for_t<It,int> range_for(It b,It e){
  return {std::move(b),std::move(e)};
}

range for only 的简单范围。可以通过完美转发来增强。

传递C 作为可能需要延长生命周期的容器。如果作为右值传递,则进行复制,否则仅引用。否则不使用。

下一部分很简单:

template<class It>
auto reverse_it(It it){
  return std::reverse_iterator<It>(std::move(it));
} 
template<class C>
auto backwards(C&&c){
  using std::begin; using std::end;
  auto b=begin(c), e=end(c);
  return range_for(
    reverse_it(e),reverse_it(b),
    std::forward<C>(c)
  );
}

这是未经测试的,但应该可以工作。

一个重要的测试是确保它在您输入右值 vec 时能正常工作,例如:

 for(auto x:backwards(make_vec()))

有效——这就是存储C 的麻烦所在。它还假设移动的容器迭代器具有表现良好的迭代器。

【讨论】:

    【解决方案3】:

    Boost 提供了一个名为 reversed 的功能,可以与 C++ 11 range based for loop 一起使用,正如 Yakk 在他的回答中所描述的那样:

    for(int i : reverse(A))
    {
      // code
    }
    

    for(int i : A | reversed)
    {
      // code
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-18
      • 1970-01-01
      • 2023-03-28
      • 2010-10-01
      • 2020-11-06
      • 1970-01-01
      • 2021-11-28
      • 1970-01-01
      相关资源
      最近更新 更多