问题
(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::...
).
来源:https://stackoverflow.com/questions/64995164/range-v3s-zip-function-works-with-temporaries-coming-from-other-range-v3s-func