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

时间:2011-06-21 21:57:14

标签: c++ boost range

有没有办法使用Boost.Range获取范围的第n个元素? (我谈论nth_element算法,如果范围被排序,它将返回第n个位置的元素。我只想根据当前的第n个元素范围内元素的顺序。)

我希望这个函数能够在前向和随机访问范围上工作(在前向范围的情况下是线性时间,在随机访问范围的情况下是恒定时间),并且抛出异常({{ 1}}}}}}如果范围少于std::out_of_range个元素。

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

编辑:实际上,使用n无法做到这一点,因为std::advance不会检查您是否超出了范围的结尾。

2 个答案:

答案 0 :(得分:2)

我没有看到内置的内容,但似乎很容易实现:

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()
    );
}

答案 1 :(得分:0)

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