【问题标题】:Transform using range-v3使用 range-v3 进行转换
【发布时间】:2019-12-16 00:35:09
【问题描述】:

我正在使用范围尝试下面的代码,但它不起作用。

// Code
std::map<int, std::string> m{ {1,"foo"},{42,"bar"},{7,"baz"} };
std::vector<int> keys;

// without using ranges
std::transform(begin(m), end(m), std::back_inserter(keys), [](auto val)
{
    return val.first;
});

这工作正常。但是,

// with using ranges
ranges::transform(m,std::back_inserter(keys), [](auto val)
{
    return val.first;
});

它不适用于范围??

我正在使用 MSVC 2017 15.9.14

【问题讨论】:

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


    【解决方案1】:

    range-v3 不支持std::back_insert_iterator,因为它不满足库Iterator 的概念,请参阅this issue。正如讨论中指出的那样,这应该用 C++20 修复。

    您可以通过以下任一方式解决此问题

    keys.resize(3);
    
    ranges::transform(m, keys.begin(), [](auto val) { return val.first; });
    

    或者,在我看来更可取(因为你可以使 keys const):

    const std::vector<int> keys = m |
        ranges::view::transform([](auto val){ return val.first; });
    

    附带说明,考虑将 lambda 参数作为const 限定引用传递以避免不必要的复制。

    【讨论】:

    • 可以更短:m | view::keys
    • 感谢@lubgr 的回答:- 这对我帮助很大。
    • 我也可以写成 const auto keys = m |范围::view::transform([](auto val){ return val.first; });
    • 不推荐将视图隐式转换为容器。您还应该通过ranges::to_vector 进行管道传输。
    • @sv90 有趣,为什么它被弃用了?
    猜你喜欢
    • 2021-03-04
    • 2023-04-04
    • 1970-01-01
    • 2020-07-26
    • 1970-01-01
    • 2019-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多