在我的应用程序中,我需要能够从列表的任意成员开始遍历双向链表,并继续经过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实现的具体内容)。
如何解决此问题?
答案 0 :(得分:1)
这里的问题是您按价值计算Container
。这会导致副本,因此container.end()
和container.begin()
返回的迭代器与传递给函数的迭代器不同。相反,如果您通过引用传递Container
,则代码可以正常工作。