Having any range as an input, how to first convert its elements to tuples and then save them in a std::map with ranges::to?
This code works and creates a vector of tuples:
#include <range/v3/all.hpp>
#include <fmt/format.h>
#include <fmt/ranges.h>
int main() {
auto v = ranges::views::iota(3, 10)
| ranges::views::transform([](auto const &v){ return std::make_tuple(v, v*2); })
| ranges::to<std::vector>();
fmt::print("{}\n", v);
}
Replacing vector by map, I'd expect to receive a map instead (with first elements of the tuples becoming keys and second elements becoming their values), but the code doesn't compile:
#include <range/v3/all.hpp>
#include <fmt/format.h>
#include <fmt/ranges.h>
int main() {
auto v = ranges::views::iota(3, 10)
| ranges::views::transform([](auto const &v){ return std::make_tuple(v, v*2); })
| ranges::to<std::map>();
fmt::print("{}\n", v);
}
I get:
test.cpp:11:10: error: invalid operands to binary expression ('invoke_result_t<ranges::views::transform_base_fn, ranges::iota_view<int, int>, (lambda at test.cpp:9:30)>' (aka 'transform_view<ranges::iota_view<int, int>, (lambda at test.cpp:9:30)>') and 'detail::to_container_fn<detail::from_range<std::map>>' (aka 'closure<ranges::detail::from_range<std::map>, ranges::detail::to_container::fn<ranges::detail::from_range<std::map>>>'))
Notes: I didn't find many examples of using ranges::to<map> in the internet, but in this answer: https://stackoverflow.com/a/74433668 there's working code where the result of ranges::views::zip is converted to a map. Since zip produces "tuple-like" elements, I expected my code to work too, but apparently it's not that straightforward.
Compiler is Clang++ v. 15.0.6, ranges is current master.
You need a std::pair, not a std::tuple (working example):
auto m = ranges::views::iota(3, 10)
| ranges::views::transform([](auto const &v){ return std::make_pair(v, v*2); })
| ranges::to<std::map>;
After all, while something like this is fine,
std::vector<std::pair<int, int>> v;
std::map<int,int> M(v.begin(), v.end());
something like this is not
std::vector<std::tuple<int, int>> v;
std::map<int,int> M(v.begin(), v.end());
Or, more simply as suggested in a comment,
std::map<int,int> P{{std::pair<int, int>{}}}; // OK
std::map<int,int> T{{std::tuple<int, int>{}}}; // Error
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With