Range recursive function (of range-v3) causes compilation to diverge: why?
For some reason, the code in the list below makes clang ++ and g ++ use 100% CPU and fill up memory until my system freezes.
Note , this is an example of a conversation game. I know that accumulate
and transform
is the standard way to do this, but this code is an intermediate point in the chain of reasoning.
#include <iostream>
#include <range/v3/all.hpp>
using namespace ranges;
template <typename F, typename R, typename T>
T rec_map_sum(F f, R r, T tally) {
if (ranges::begin(r) == ranges::end(r))
return tally;
else {
auto r_head = *ranges::begin(r);
auto r_tail = r | view::drop(1);
return rec_map_sum(f, r_tail, tally + f(r_head));
// this also crashes:
// return rec_map_sum(f, r[{1, end}], tally + f(r_head));
}
}
int main() {
std::cout << rec_map_sum([](int x) { return x * x; }, view::iota(0, 10), 0)
<< std::endl;
return 0;
}
The function is rec_map_sum
designed to implement recursion, which takes a range of integers and a unary function, applies an element to the range, and produces the sum of the displayed elements.
I have two questions: (1) what is the reason for the diverging behavior, and (2) how do I make and pass the tail representation so that the compilation doesn't work?
source to share
The problem is pointed out by Jarod42, but the solution is pretty simple. You need an erasable view type that can take any range. Fortunately, such a thing exists . Change your code to:
template <typename F, typename R, typename T>
T rec_map_sum(F f, R r, T tally) {
auto r2 = any_view<T>{r};
if (ranges::begin(r2) == ranges::end(r2))
return tally;
else {
auto r_head = *ranges::begin(r2);
auto r_tail = r2 | view::drop(1);
return rec_map_sum(f, r_tail, tally + f(r_head));
}
}
Will print 285.
source to share