Предотвращение прохождения итератора за концом контейнера - PullRequest
0 голосов
/ 25 февраля 2019

Я работаю над своей собственной for_each функцией типа с некоторым целым числом N.

Вот как моя функция выглядит в настоящее время:

template<typename Container, typename Function>
void for_each_by_n( Container&& cont, Function f, unsigned increment_by ) {
    using std::begin;
    auto it = begin(cont);

    using std::end;
    auto end_it = end(cont);

    while ( it != end_it ) { // traverse the full container
        f(*it);  // call the function pointer - object etc.
        for ( unsigned n = 0; n < increment_by; ++n ) {
            // here I want to increment the pointer as long as the next iteration of
            // increment_by is within the bounds of the range of the container
            if ( .... tried many things .... ) return; // and or break;
            ++it;
        }
    }
}

Моя последняя попыткаВнутренний оператор if был следующим:

if ( n % increment_by > (cont.size() - n) ) return; // and or break;

Однако я продолжаю получать ошибку отладочного утверждения, что не могу выполнить итерацию после конца индекса контейнера.Это поставило меня в тупик, и я не знаю, как предотвратить повторение итерации до конца.

Ответы [ 2 ]

0 голосов
/ 25 февраля 2019

Хорошо, я отошел от компьютера примерно на 30 секунд, а потом он пришел ко мне.Я был полностью из-за этого, и это было на самом деле простое исправление.

Все, что мне нужно было сделать для оператора if, было так:

if ( it == end_it ) return;

Теперь все работает правильно.Не было необходимости делать расчеты, основываясь на том, где указатель индекса сравнивался с концом.Все, что мне нужно было сделать, это сравнить, если они равны, и если это так, просто вернуть.

Таким образом, полная завершенная функция теперь выглядит так:

// positive direction from begin to end only
template<typename Container, typename Function>
void for_each_by_n(Container&& cont, Function f, unsigned increment_by) {
    using std::begin;
    auto it = begin(cont);

    using std::end;
    auto end_it = end(cont);

    while (it != end_it ) {
        f(*it);
        for ( unsigned n = 0; n < increment_by; ++n ) {
            if (it == end_it) {
                return;
            }
            ++it;
        }
    }
}

Должно быть, это был синдром coders_block...

0 голосов
/ 25 февраля 2019

Ключевым моментом здесь является осознание того, что вам нужен первый элемент каждого фрагмента cont, а каждый фрагмент - increment_by элементов.Следовательно, есть cont.size()/increment_by куски.Не нужно проверять, достигли ли вы последнего итератора, просто посчитайте куски.

Нет необходимости в ++it.Используйте std::advance(increment_by), это намного быстрее для итераторов с произвольным доступом.

...