2013-06-20 3 views
0

У меня есть фрагмент кода, который использует std::advance().std :: advance() вызывает бесконечный цикл

Как избежать бесконечного цикла при использовании std::advance()?

std::list<xxx>::iterator i = ppp.begin(); 
std::advance(i, yyy); 
+3

huh. Что такое yyy? И когда вы получаете бесконечный цикл? Посмотрите: нет проблем ** [http://ideone.com/seovl5] (http://ideone.com/seovl5) ** – sehe

ответ

1

Возможно, вы имеете в виду, как вы должны избегать прохода мимо конца() итератора.

В этом случае, либо просто проверка

std::advance(i, std::min(yyy, std::distance(i, ppp.end())); 

Или написать обертку станд :: опережения/станд :: следующий, который проверяет для конечных итераторов более efficienttly: http://ideone.com/7DYSSn

#include <list> 
#include <cassert> 

template <typename It> 
    It safe_next(It it, std::size_t steps, It end) 
{ 
    while (it!=end && steps--) 
     it++; 

    return it; 
} 

int main() 
{ 
    std::list<int> l { 1,2,3,4,5,6,7,8 }; 
    auto it = begin(l); 

    assert(safe_next(it, 3, end(l)) == std::next(it, 3)); 
    assert(safe_next(it, 30, end(l)) == end(l)); 

    // the `distance` trick also works: 
    assert(next(it, std::min(30l, std::distance(it, end(l)))) == end(l)); 
} 

Примечание, который проходит мимо конца Неопределенное поведение, что совершенно иное, чем бесконечный цикл. Это может иметь тот же «очевидный» эффект (но, конечно же, это характер UB).