Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ranges-v3 join function to join two containers together

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.

like image 260
Andrew Avatar asked Mar 02 '23 13:03

Andrew


1 Answers

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.

like image 51
Enlico Avatar answered Mar 29 '23 14:03

Enlico