2015-11-19 242 views
1

在我的应用程序中,我需要遍历从列表的任意成员开始的双向链表,并继续通过end(),环绕到begin()并继续,直到遍历到达它开始的地方。std :: list的循环迭代

我决定使用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

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

Live Example