Предположим, у меня есть некоторый код на основе массива, который разрешен для использования шаблонами выражений. Например, у меня есть operator[]
для этих массивов перегруженным, а также перегружен арифметический оператор +
т.д.Могут ли алгоритмы быть совместимыми с шаблонами выражений?
Теперь я хотел бы позволить STL алгоритм any_of
работать на таких массивах. Простой способ сделать
ExprArray<double, N> b, c; // init etc.
auto a = b + c; // for (auto i = 0; i < N; ++i) { a[i] = b[i] + c[i]; }
auto res = std::any_of(begin(a), end(a), SomePred{});
Конечно, я хотел бы быть в состоянии короткого замыкания вычисления и имеют модифицированную (диапазон на основе) lib::any_of
, что делает
// only compute b[i] + c[i] until SomePred is satisified
auto res = lib::any_of(b + c, SomePred{}); // write as explicit loop over b[i] + c[i]
Дать lib::any_of
в условия operator[]
на его входе будут выполнять эту работу, как это было сделано для перегруженного operator+
. Однако для этого потребуются аналогичные повторные реализации всех алгоритмов STL, которые я мог бы запускать на таких массивах.
Вопрос: Так предположим, что я хочу, чтобы повторно использовать существующие алгоритмы диапазона на основе (Boost.Range, диапазон-v3) лишь модификацией ExprArray iterators
. Возможно ли изменить итератор ExprArray
operator*
и operator++
таким образом, чтобы это было прозрачным для алгоритмов на основе диапазонов?
// only compute b[i] + c[i] until SomePred is satisified
// needs to eventually dispatch to
// for (auto i = 0; i < N; ++i)
// if (SomePred(b[i] + c[i])) return true;
// return false;
auto res = ranges::any_of(b + c, SomePred{});
Таким образом, если версия алгоритма на самом деле реализуется в терминах итераторов, цикл for (auto it = first; it != last; ++it)
нужно *it
, чтобы быть в курсе того, что он должен вычислить b[i] + c[i]
и ++it
должен знать, что он должен делать ++i
.
Остановить, когда предикат является истинным, должно быть естественным делом для 'std :: any_of', вы проверили, что этого еще не сделано? (Вы можете сделать это, передав лямбду, которая печатает значения, которые она получает как предикат.) –
@JoachimPileborg остановка на самом деле не проблема, это ленивое вычисление шаблона выражения и его итераторов начала и конца. Если я только перегрузил 'operator []', мне нужна реализация на основе итератора, чтобы знать, что он получает шаблон выражения и переводит '* it' в соответствующий' expr [i] '. Вопрос в том, может ли 'operator * 'итератора делать для меня такую работу? – TemplateRex
@TemplateRex обратите внимание, что вопрос об алгоритме C++ библиотеки не связан с дизайном алгоритма, поэтому тег алгоритма неуместен –