如何使用 Range-v3 模拟 boost::algorithm::find_if_backward?

问题描述

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

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

这是我的尝试,看起来有点笨重;我什至不确定它是否足够健壮。实际上,正如评论中所建议的,代码 不够健壮,因为当找不到元素时,range_it_to_last_2 最终会变成 std::next(v.begin(),-1),这是未定义的行为,我相信.

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

解决方法

假设您总是知道找到了匹配项,为什么不简化为以下内容,获得相同的输出:

Live On Godbolt

#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,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),range_match));
}

印刷品

boost: {0,2}
range: {0,2}

(一些玩具重新拼写的乐趣:https://godbolt.org/z/ccPKeo

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...