LINUX.ORG.RU

История изменений

Исправление quasimoto, (текущая версия) :

Т.е. фактически range отличается от итератора только тем, что сама проверяет не дошла ли до конца?

В первом приближении это пара «обычных» итераторов, так что, да, всё есть — можно реализовать empty() и прочие вещи. Но вообще суть в том что это именно единственный объект для каждого вида обхода для данного контейнера — с любым подходящим интерфейсом для обобщённого кода в виде свободных шаблонных функций. И то что это единственный объект позволяет, например, делать вещи вроде ReversedRange<ARange> reverse(ARange), SequentialRange<ARange, BRange> seq(ARange, BRange), ParallelRange<ARange, BRange> par(ARange, BRange) и т.п.

Мне интересно, как сообщить «обходчику» что ему делать с каждым элементом и как вернут итоговый результат.

http://www.cplusplus.com/reference/algorithm/ и http://www.cplusplus.com/reference/numeric/ это не то? Если обощённость не нужна, то для конкретного класса можно тогда стереть итераторы из шаблонов и заменить функторы на обычные ссылки на функции, вроде

template <typename R, typename A, typename ...As>
using AccumulateFunction = R(&)(R, A, As...);

template <typename R, typename A, typename ...As>
R accumulate(ThisClass<A> &obj, AccumulateFunction<R, A, As...> fn)
{
    // traverse, parallelize, prepeare As... from obj for user's callback (including "context", "hints" and so on)
}

template <typename R, typename A, typename ...As>
R accumulate(ThisClass<A> &obj, AccumulateFunction<R, A, As...> fn, R init)

// min = accumulate(obj, *[](T acc, T el) { return el < acc ? el : acc; });
// sum = accumulate(obj, std::plus<T>(), 0);

также с for_each, find_if и т.п. Только будучи свободными функциям им всем всё равно нужно опираться на какие-то методы обхода ThisClass, или просто на его кишки (будучи выделенными в отдельные сущности они превращаются, собственно, в итераторы и ко).

обход может быть например рекурсивным, разворачивать рекурсию ручками по ряду причин не хочется и не можется

Это да, если структура данных неудобная в итеративном смысле то без её «прошивания» (то есть дополнения связями) может не получиться эффективного обхода.

ну допустим под каждый тред можно сваять свой range

Выше у меня в async_fold как раз в лямбду для async копируется ([=]) range элементов массива полученный как срез из range срезов массива.

Исходная версия quasimoto, :

Т.е. фактически range отличается от итератора только тем, что сама проверяет не дошла ли до конца?

В первом приближении это пара «обычных» итераторов, так что, да, всё есть — можно реализовать empty() и прочие вещи. Но вообще суть в том что это именно единственный объект для каждого вида обхода для данного контейнера — с любым подходящим интерфейсом для обобщённого кода в виде свободных шаблонных функций. И то что это единственный объект позволяет, например, делать вещи вроде ReversedRange<ARange> reverse(ARange), SequentialRange<ARange, BRange> seq(ARange, BRange), ParallelRange<ARange, BRange> par(ARange, BRange) и т.п.

Мне интересно, как сообщить «обходчику» что ему делать с каждым элементом и как вернут итоговый результат.

http://www.cplusplus.com/reference/algorithm/ и http://www.cplusplus.com/reference/numeric/ это не то? Если обощённость не нужна, то для конкретного класса можно тогда стереть итераторы из шаблонов и заменить функторы на обычные ссылки, вроде

template <typename R, typename A, typename ...As>
using AccumulateFunction = R(&)(R, A, As...);

template <typename R, typename A, typename ...As>
R accumulate(ThisClass<A> &obj, AccumulateFunction<R, A, As...> fn)
{
    // traverse, parallelize, prepeare As... from obj for user's callback (including "context", "hints" and so on)
}

template <typename R, typename A, typename ...As>
R accumulate(ThisClass<A> &obj, AccumulateFunction<R, A, As...> fn, R init)

// min = accumulate(obj, *[](T acc, T el) { return el < acc ? el : acc; });
// sum = accumulate(obj, std::plus<T>(), 0);

также с for_each, find_if и т.п. Только будучи свободными функциям им всем всё равно нужно опираться на какие-то методы обхода ThisClass, или просто на его кишки (будучи выделенными в отдельные сущности они превращаются, собственно, в итераторы и ко).

обход может быть например рекурсивным, разворачивать рекурсию ручками по ряду причин не хочется и не можется

Это да, если структура данных неудобная в итеративном смысле то без её «прошивания» (то есть дополнения связями) может не получиться эффективного обхода.

ну допустим под каждый тред можно сваять свой range

Выше у меня в async_fold как раз в лямбду для async копируется ([=]) range элементов массива полученный как срез из range срезов массива.