I ran into this problem while trying to make a powerset function using the std::views library.
auto set = sv::repeat(0) | sv::take_while([&mask](...) { return mask > 0; }) | sv::transform([s, &mask, idx = 0](...) mutable { return idx = std::countr_zero(mask & ~(mask - 1)), mask &= mask - 1, s[idx]; });auto vec = std::vector(set.begin(), set.end()); ^__________ ^______________________"*cannot deduce types*" "*no constructor found*" <- these are rough translations of verbose diagnostics
My question is, why doesn't this work? Normally I can construct vectors using views like this perfectly well, and I even do it later in the function.I tested the same thing, but this time I used a captureless and const lambda:
auto arr = std::array {1, 2, 3, 3, 4, 5, 6, 1, 2, 3};auto arr_view = arr | std::views::take_while([](int i) { return i < 4; });auto vec = std::vector(arr_view.begin(), arr_view.end());
and got identical error messages.Stranger still, I tried using the std::ranges::move()
function to do the same thing, and it worked for some reason!This code compiles and runs as expected (both with the constructed view as an rvalue and stored in a variable):
auto arr_view = arr | std::views::take_while([](int i) { return i < 4; });auto vec = std::vector<int>{};std::ranges::move(arr_view, std::back_inserter(vec));
Initially, I thought this was because "arr_view" wasn't a sized range, but the same iterative approach of construction works for std::views::filter()
, which is also not a sized range.Can someone explain to me the reasoning behind this not working? Is it just me using (unstable) modern features?