优雅的方式来有条件地正向或反向迭代

7

我需要根据一个布尔值,对一个std::vector进行正向或反向处理。最优雅的方法是什么?在需要反向处理之前,我的代码如下:

BOOST_FOREACH(const CType &foo, vec) {
    ...
}

然而,现在我有一个看起来非常可怕的问题:
for (int i=undoing ? (vec.size()-1) : 0; undoing ? (i >= 0) : (i < vec.size()); undoing ? (i--) : (i++)) {
    const CType &foo = vec[i];
    ...
}

有更好的方法吗?

4个回答

8
添加一个可以与正向迭代器或反向迭代器一起使用的模板函数。根据undoing的值使用相应的迭代器调用该函数。
template <typename Iterator>
void doStuff(Iterator iter, Iterator end)
{
   for ( ; iter != end; ++iter )
   {
      // Do stuff
   }
}

if ( undoing )
{
   doStuff(vec.rbegin(), vec.rend());
}
else
{
   doStuff(vec.begin(), vec.end());
}

8

我不知道人们是否会称其为优雅,但有以下内容:

auto do_it = [](const CType& elem)
             {
                 ...
             };
if (iterate_forward) {
    std::for_each(vec.begin(), vec.end(), do_it);
}
else {
    std::for_each(vec.rbegin(), vec.rend(), do_it);
}

5
如何保持循环从0到vector.size的运行,但按所需方向读取数组。
int idx;
for (int i =0; i < vec.size(); i ++)
{
   if (undoing) // assuming going forward
     idx = i;
   else // going backwards
     idx = vec.size() - i - 1;

  const CType &foo = vec[idx];
}

3
您也可以使用基于Boost.Range的解决方案。它与使用STL算法的已经提出的解决方案类似。
#include <boost/range/adaptor/reversed.hpp>
#include <boost/range/algorithm/for_each.hpp>

// In C++11 lambda expression can be used instead
struct my_fun
{
    void operator()(const CType& elem) const
    {
        /*...*/
    }
};

/*...*/

using namespace boost::adaptors;

if ( iterate_forward )
    boost::for_each(my_vect, my_fun());
else
    boost::for_each(my_vect | reversed, my_fun());

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接