I've been trying to understand the Range-v3 join
documentation but I'll be honest, I don't understand it. And I've not been able to find any relevant examples either.
Could someone show me how to create a joined view of two deque vectors please. I've already tried these methods but to no avail.
#include <range/v3/all.hpp>
#include <deque>
#include <iostream>
struct data_t
{
int data;
int some_other_data;
};
auto main() -> int
{
using namespace ranges;
auto v1 = std::deque<data_t>() = { {1,1}, {2,2}, {3,3}, {4,4}, {5,5} };
auto v2 = std::deque<data_t>() = { {6,6}, {7,7}, {8,8}, {9,9}, {10,10} };
auto vv = v1 | ranges::actions::join(v2);
// auto vv = ranges::actions::join(v1, v2); // Tried this too
for(auto v : vv)
{
std::cout << v.data << ", " << std::endl;
}
return 0;
}
Here's a live demo.
As a general suggestion, whenever you want the documentation for something which is in Range-v3, you better pray it is in C++20 too and refer to that. That's the case for join
(but not for concat
, apparently).
You're looking for concat
, not join
:
#include <range/v3/view/concat.hpp>
#include <iostream>
#include <vector>
using ranges::views::concat;
int main() {
std::vector<int> v{1,2,3};
std::vector<int> w{4,5,6};
std::cout << concat(v,w) << std::endl; // prints [1,2,3,4,5,6]
}
join
is for something else, namely collapsing two nested ranges:
#include <range/v3/view/join.hpp>
#include <iostream>
#include <vector>
using ranges::views::join;
int main() {
std::vector<std::vector<int>> w{{1,2,3},{4},{5,6}};
std::cout << (w | join) << std::endl; // prints [1,2,3,4,5,6]
}
Notice that join
(which is called join
in some other languages too, like Haskell, and flatten
somewhere else) is a very important concept in functional programming.
Indeed, when I write collapsing two nested ranges, I'm being fairly approximative, because Haskell's join
(or the true meaning of join
/flatten
/whatever is called in category theory) is much more profound than that. For instance, in Haskell it's true that join (Just (Just 3)) == Just 3
, which in C++ you'd write as
std::optional<std::optional<int>>{3} | join /* not Range-v3's */ == std::optional<int>{3}
What Haskell's join
really does is collapsing two nested monads. For reference in C++, you might want to give a look at Boost.Hana and specifically at the documentation of the Monad
concept.
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