Boost.Range算法,用于获取范围的第n个元素

Boost.Range algorithm for getting the nth element of a range

本文关键字:元素 范围 获取 Range 算法 用于 Boost      更新时间:2023-10-16

是否有方法使用Boost.range获取范围的第n个元素?(我不是在谈论nth_element算法,如果对范围进行排序,该算法将返回第n个位置的元素。我只是希望根据范围中元素的当前顺序来选择第n个元素)。

我希望这个函数同时适用于前向和随机接入范围(在前向范围的情况下是线性时间,在随机接入范围的情况中是恒定时间),并且如果该范围的元素少于n,则抛出异常(可能是std::out_of_range)。

我知道这可以通过std::advance将范围的begin()迭代器n来实现,但我正在寻找一种基于范围的解决方案,它不会下降到迭代器的级别。

EDIT:实际上,std::advance无法执行此操作,因为std::advance不会检查您是否已超过范围的末尾。

我没有看到任何类似的内置功能,但它似乎很容易实现:

namespace details {
template<typename RangeT, typename IterCatT>
typename boost::range_reference<RangeT>::type nth_impl(
    RangeT& range,
    typename boost::range_difference<RangeT>::type n,
    IterCatT const)
{
    typedef typename boost::range_iterator<RangeT>::type iter_t;
    iter_t first = boost::begin(range), last = boost::end(range);
    while (n--)
        if (++first == last)
            throw std::range_error("n");
    return *first;
}
template<typename RangeT>
typename boost::range_reference<RangeT>::type nth_impl(
    RangeT& range,
    typename boost::range_difference<RangeT>::type const n,
    std::random_access_iterator_tag const)
{
    if (boost::size(range) <= n)
        throw std::range_error("n");
    return *(boost::begin(range) + n);
}
}
template<typename RangeT>
typename boost::range_reference<RangeT>::type nth(
    RangeT& range,
    typename boost::range_difference<RangeT>::type const n)
{
    return details::nth_impl(
        range,
        n,
        typename boost::range_category<RangeT>::type()
    );
}

我遇到了类似的问题。我使用boost::adapter::striped解决了这个问题。