首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用Range-v3仿真boost::algorithm::find_if_backward?

如何用Range-v3仿真boost::algorithm::find_if_backward?
EN

Stack Overflow用户
提问于 2021-02-17 09:59:13
回答 1查看 71关注 0票数 1

我一直在广泛地使用boost::algorithm::find_if_backward来获得满足谓词范围内的最后一个元素的前向迭代器。

如何使用Range-v3完成相同的任务?

这是我的尝试,看上去有点笨重;我甚至不确定它是否足够健壮。实际上,正如注释中所建议的那样,代码不够健壮,因为当没有找到任何元素时,range_it_to_last_2最终是std::next(v.begin(), -1),我相信这是未定义的行为。

代码语言:javascript
复制
#include <algorithm>
#include <boost/algorithm/find_backward.hpp>
#include <boost/hana/functional/partial.hpp>
#include <iostream>
#include <range/v3/algorithm/find_if.hpp>
#include <range/v3/view/reverse.hpp>

using boost::algorithm::find_if_backward;
using ranges::find_if;
using ranges::views::reverse;

auto constexpr is_2 = boost::hana::partial(std::equal_to<>{}, 2);

int main() {
    std::vector<int> v{0,1,2,2,2,3};

    // What I have been doing so far:
    auto boost_it_to_last_2 = find_if_backward(v, is_2);

    // The Range-v3 analogous I could come up with, but it's ugly:
    auto range_it_to_last_2 = std::next(find_if(v | reverse, is_2).base(), -1);

    for (auto it = v.begin(); it <= boost_it_to_last_2; ++it) {
        std::cout << *it << ' ';
    } // prints 0 1 2 2 2
    std::cout << std::endl;
    for (auto it = v.begin(); it <= range_it_to_last_2; ++it) {
        std::cout << *it << ' ';
    } // prints 0 1 2 2 2
    std::cout << std::endl;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-02-17 15:52:53

假设您始终知道找到了匹配项,那么为什么不简化为下面的内容,得到相同的输出:

住在哥德波特

代码语言:javascript
复制
#include <algorithm>
#include <boost/algorithm/find_backward.hpp>
#include <boost/hana/functional/partial.hpp>
#include <fmt/ranges.h>
#include <range/v3/algorithm/find_if.hpp>
#include <range/v3/view/subrange.hpp>
#include <range/v3/view/reverse.hpp>

using boost::algorithm::find_if_backward;
using ranges::find_if;
using ranges::views::reverse;
using ranges::subrange;

auto constexpr pred = boost::hana::partial(std::equal_to<>{}, 2);

int main() {
    std::vector<int> v {0,1,2,2,2,3};
    auto boost_match = find_if_backward(v, pred);
    auto range_match = find_if(v | reverse, pred).base();

    static_assert(std::is_same_v<decltype(boost_match), decltype(range_match)>);

    fmt::print("boost: {}\nrange: {}\n",
            subrange(v.begin(), boost_match+1),
            subrange(v.begin(), range_match));
}

打印

代码语言:javascript
复制
boost: {0, 1, 2, 2, 2}
range: {0, 1, 2, 2, 2}

(一些好玩的玩具呼吸:https://godbolt.org/z/ccPKeo)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66239603

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档