Пользовательский контейнерный обход с использованием диапазона для цикла - PullRequest
5 голосов
/ 03 мая 2020

В C ++ некоторые STL-контейнеры, такие как vector, map, string, могут просматриваться для циклов с двоеточием в нем.

например:

for(auto c:v)

Когда я пишу собственный контейнер, могу ли я сделать так, чтобы он проходил таким образом, как Java (который нужен только для реализации Iterable)?

Ответы [ 2 ]

5 голосов
/ 03 мая 2020

Да, вам нужно реализовать некоторую форму итератора и переопределить std :: begin (container) и std :: end (container) (может также работать, если у вашего контейнера есть методы begin и end).

Внутренне код эквивалентен чему-то вроде следующего (это просто для понимания, компилятор может написать это немного по-другому, подробнее см. здесь ).

auto _end = end(v);
for (auto _it = begin(v); _it != _end; ++_it) {  
    auto c = *_it;
    <the rest of loop code>
}

Так что, если ваш итератор и переопределения работают должным образом, он будет работать и для l oop.

0 голосов
/ 03 мая 2020

У вас может быть следующий простой эквивалент Java Iterable интерфейса:

template <typename T, typename U>
struct iterable {
    T _begin;
    U _end;

    iterable(T begin, U end)
        : _begin(begin),
          _end(end)
    {}

    T begin() {
        return _begin;
    }

    U end() {
        return _end;
    }
};

Если вам интересно, почему существуют T и U, когда начальный и конечный итератор должен быть то же. Причина в том, что некоторые контейнеры не имеют этих двух итераторов одного типа.

Кроме того, вы можете реализовать вспомогательную функцию make_iterable, например:

template <typename T, typename U>
iterable<T, U> make_iterable(T t, U u) {
    return iterable<T,U>(t, u);
}
...