(This is kind of a follow up to this other question.)
Original question
The following code works just fine
#include <boost/range/adaptor/transformed.hpp>
#include <cmath>
#include <range/v3/view/zip.hpp>
#include <string>
#include <vector>
int main() {
auto vec1 = std::vector<int>{1,2,3};
auto vec2 = std::vector<std::string>{"uno","due","tre"};
auto sqrt = [](auto x){ return std::sqrt(x); };
auto vec3 = vec1 | boost::adaptors::transformed(sqrt);
for (auto const& i : ranges::views::zip(vec1, vec2, vec3)) {
// whatever
}
}
but what if I want to avoid storing the result in vec3? Ok, without | to_vector vec3 is just a view (right?), so storing it is not a big memory usage concern, but bear with me. Chaging the for line to the following does not work
for (auto const& i : ranges::views::zip(vec1, vec2, vec1 | boost::adaptors::transformed(sqrt))) {
The answer from a comment
Based on a comment, I just didn't think much about the problem before posting the question, as the solution as simple as using ranges::views::transform instead of boost::adaptors::transformed.
I'd still like to understand what was going on
At this point, however, I'm honestly still interested in understanding what's wrong with the former solution.
I initially I thought that ranges::views::zip couldn't work with temporaries, but the solution above (in italic) proves me wrong, as vec1 | ranges::views::transform(sqrt) is still a temporary, not an lvalue.
On the other hand, it's also true that ranges::views::zip(vec1, vec2, std::move(vec3)) fails, where std::move(vec3) is also not an lvalue, but an xvalue.
It'd be good if someone could help me understand the peculiarities of ranges::views::zip and why it works with some temporaries (I'd say those coming from other Range-v3 functions) but not others (e.g. xvalues coming std::move or a true temporary coming from boost::...).