双向遍历容器

时间:2018-08-09 17:45:26

标签: c++ c++11 iterator stdmap

是否有比下面的代码更好的方法,可以使用相同的迭代器在任一方向上对容器进行迭代?

#include <iostream>
#include <map>

int main()
{
    const bool descend = false;

    std::map<int, int> mapp;
    mapp[1] = 1;
    mapp[2] = 2;
    mapp[3] = 3;
    mapp[4] = 4;

    std::map<int, int>::iterator startIter = descend ? --(mapp.end()) : mapp.begin();
    std::map<int, int>::iterator endIter = descend ? --(mapp.begin()) : mapp.end();

    while (startIter != endIter)
    {
        std::cout << startIter->first << std::endl;
        descend ? --startIter : ++startIter;
    }
}

3 个答案:

答案 0 :(得分:2)

  

是否有比下面的代码更好的方法来遍历容器   在任何一个方向上,使用相同的迭代器?

。使用std::map::reverse_iterator。这将是比您发布的代码更好的方法,但是那将不再使用相同的迭代器,这是您的要求之一。

但是,这将比您编写的代码少出错。除此之外,如果已经在C ++中,您不需要重新发明轮子。

See output here

#include <iostream>
#include <map>

template<typename Iterator>
void print(const Iterator Begin, const Iterator End)
{
    for(Iterator iter = Begin; iter != End; ++iter)
       std::cout << iter->first << "\n";
}

int main()
{
    const bool descend = true;

    std::map<int, int> mapp;
    mapp[1] = 1;
    mapp[2] = 2;
    mapp[3] = 3;
    mapp[4] = 4;

    descend ?
        print(mapp.crbegin(), mapp.crend()):
        print(mapp.cbegin(), mapp.cend());
    return 0;
}

cppreference.com中的图片将以图形方式说明其运作方式。 enter image description here

答案 1 :(得分:2)

您的代码无效,因为此语句--(mapp.begin())导致UB。我会写一个薄包装纸:

template<class Iter, class F>
void apply( Iter begin, Iter end, F f, bool forward )
{
    while( begin != end ) 
        f( forward ? *begin++ : *--end );
}

live example

或者只是将循环重写为:

auto begin = mapp.begin();
auto end = mapp.end();
while ( begin != end)
{
    const auto &p = forward ? *begin++ : *--end;
    std::cout << p.first << std::endl;
}

答案 2 :(得分:-1)

编写自文档代码,它变得很简单。将循环拆分成自己的函数,并使用适当的迭代器对其进行调用。

这就是为什么我们有“反向迭代器”的原因,它们可以通过使用正常的向前语义在容器中向后移动。

#include <iostream>
#include <map>

template<typename I>
void printMapContainer(I begin, I end)
{
    for (;begin != end; ++begin)
    {
        std::cout << begin->first << "\n";
    }
}
int main()
{
    const bool descend = false;

    std::map<int, int> mapp;
    mapp[1] = 1;
    mapp[2] = 2;
    mapp[3] = 3;
    mapp[4] = 4;

    if (descend) {
        printMapContainer(mapp.rbegin(), mapp.rend());
    }
    else {
        printMapContainer(mapp.begin(), mapp.end());
    }
}