Why do I need to evaluate range-v3 views to be able to use them with concat?

Viewed 95

I’m trying to concatenate multiple views on a move-only type:

using namespace ranges;
auto v = views::ints(0, 4) |
         views::transform([](int i) { return std::make_unique<int>(i); });
auto w = views::ints(4, 8) |
         views::transform([](int i) { return std::make_unique<int>(i); });
auto x = views::concat(v, w) | to<std::vector>();

However, this does not compile for me and I can’t make much sense of the error message (see https://godbolt.org/z/TcoP8djnz).

If I choose to evaluate v and w first, though, the code compiles:

auto v = views::ints(0, 4) |
         views::transform([](int i) { return std::make_unique<int>(i); }) |
         to<std::vector>();
auto w = views::ints(4, 8) |
         views::transform([](int i) { return std::make_unique<int>(i); }) |
         to<std::vector>();
auto x = views::concat(v | views::move, w | views::move) | to<std::vector>();

Why is that? According to the range-v3 doxygen the requirements are that the parameters to concat are viewable_ranges and input_ranges. While I’m not sure I fully understand the meaning of the former concept, I think that both of these requirements should be met even in the first case.

Btw, the first case also compiles when I replace make_unique with make_shared, i.e. I replace it with a copyable type.

0 Answers
Related