std :: list

时间:2015-11-19 20:21:53

标签: c++ c++11 stl

在我的应用程序中,我需要能够从列表的任意成员开始遍历双向链表,并继续经过end(),回绕到begin()并继续,直到遍历到达它开始的位置。 / p>

我决定使用std::list作为底层数据结构,并编写了一个circulate例程来实现这一目标。然而,当它从end()到begin()包装时,它显示出某些意想不到的行为。这是我的实现

template <class Container, class BiDirIterator>
void circulate(Container container, BiDirIterator cursor,
  std::function<void(BiDirIterator current)> processor)
{
  BiDirIterator start = cursor;
  do {
    processor(cursor);
    cursor++;
    if (cursor == container.end()) {
      cursor = container.begin(); // [A]
    }
  } while (cursor != start);
}

// ...

typedef int T;
typedef std::list<T> TList;
typedef TList::iterator TIter;

int count = 0;
TList l;
l.push_back(42);
circulate<TList, TIter>(
  l, l.begin(),
  [&](TIter cur) {
    std::cout << *cur << std::endl;
    count++;
  }
);

输出结果为:

42
-842150451

当我单步执行代码时,我发现永远不会到达标记为[A]的行。光标永远不会等于container.end()。令人惊讶的是,在该游标上调用++会自动将其带到container.begin()。 (我想这是STL实现的具体内容)。

如何解决此问题?

1 个答案:

答案 0 :(得分:1)

这里的问题是您按价值计算Container。这会导致副本,因此container.end()container.begin()返回的迭代器与传递给函数的迭代器不同。相反,如果您通过引用传递Container,则代码可以正常工作。

Live Example