ranges-v3 join 函数将两个容器连接在一起

ranges-v3 join function to join two containers together

我一直在努力理解 Range-v3 join 文档,但老实说,我不明白。而且我也没能找到任何相关的例子。

有人可以告诉我如何创建两个双端队列向量的联合视图吗?我已经尝试过这些方法,但无济于事。

#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;
}

这是一个 live 演示。

作为一般性建议,每当您需要 Range-v3 中的文档时,请祈祷它也在 C++20 中,并参考它。 join 就是这种情况(但显然 concat 不是)。

您正在寻找 concat,而不是 join:

#include <range/v3/view/concat.hpp>
#include <iostream>
#include <vector>

int main() {
    std::vector<int> v{1,2,3};
    std::vector<int> w{4,5,6};
    std::cout << ranges::views::concat(v,w) << std::endl; // prints [1,2,3,4,5,6]
}

join 用于其他用途,即折叠两个嵌套范围:

#include <range/v3/view/join.hpp>
#include <iostream>
#include <vector>

int main() {
    std::vector<std::vector<int>> w{{1,2,3},{4},{5,6}};
    std::cout << (w | ranges::views::join) << std::endl; // prints [1,2,3,4,5,6]
}

请注意 join(在某些其他语言中也称为 join,例如 Haskell,在其他地方称为 flatten)是函数式中非常重要的概念编程。

确实,当我写 折叠两个嵌套的 范围 时,我是相当近似的,因为 Haskell's join(或join/flatten/范畴论中所谓的)的真正含义比这要深刻得多。例如,在 Haskell 中 join (Just (Just 3)) == Just 3 是真的,在 C++ 中你会写成

std::optional<std::optional<int>>{3} | join /* not Range-v3's */ == std::optional<int>{3}

Haskell 的 join 真正做的是 折叠两个嵌套的 monads。对于 C++ 中的参考,您可能想看看 Boost.Hana and specifically at the documentation of the Monad 概念。