2015-11-19 98 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