ericniebler/range-v3

generate seems broken with move-only return types

mikezackles opened this issue · 3 comments

I haven't been able to get anything that uses this view to compile:

auto rng = view::generate_n([]()->MoveOnlyString{ return {"Hello, world!"}; }, 4);

godbolt

The issue seems to revolve around the cached value stored by view::generate_n (and view::generate).

To me this seems like an important use case, but hopefully I'm just misunderstanding something!

FWIW, I can work around this with something like this:

auto rng = view::repeat_n(0, 4) | view::transform([](auto)->MoveOnlyString{ return {"Hello, world!"}; });

FYI, the reason that your workaround works is because view::transform assumes that transformation function is a regular function; that is, that different invocations of it with the same argument yield the same result. The generate views can't make that assumption, and so needs to cache the value in order to satisfy the semantic requirements of the InputIterator concept: namely, that when evaluated multiple types without an intervening increment, *i always yields the same value.

Cool, thanks for the clarification and the quick fix! I was trying something similar but couldn't manage to get it quite right.