首页 > 解决方案 > range-v3 join 函数将两个容器连接在一起

问题描述

我一直在尝试理解 Range-v3join文档,但老实说,我不明白。而且我也找不到任何相关的例子。

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

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

这是一个现场演示。

标签: c++c++20range-v3

解决方案


作为一般建议,每当您想要 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 的joinjoin(或/ / 范畴论中所谓的任何东西的真正含义flatten)比这要深刻得多。例如,在 Haskell 中确实是join (Just (Just 3)) == Just 3,在 C++ 中你可以写成

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

Haskelljoin真正做的是折叠两个嵌套的单子。对于 C++ 中的参考,您可能需要查看Boost.Hana,特别是该Monad概念的文档。


推荐阅读