Алгоритм Boost.Range для получения n-го элемента диапазона - PullRequest
2 голосов
/ 22 июня 2011

Есть ли способ получить n-й элемент диапазона, используя Boost.Range?(Я не говорю об алгоритме nth_element, который возвращает элемент, который был бы в n-й позиции, если бы диапазон был отсортирован. Я просто хочу, чтобы n-й элемент соответствовал текущему порядку элементовв диапазоне).

Я ожидал бы, что эта функция будет работать как в диапазонах прямого, так и произвольного доступа (линейное время в случае диапазонов прямого диапазона и постоянное время в случае диапазонов произвольного доступа),и выдать исключение (возможно, std::out_of_range), если диапазон содержит менее n элементов.

Я знаю, что это можно сделать, std::advance -ing итератор begin() диапазона * n, но я ищу решение на основе диапазона, которое не опускается до уровня итераторов.

EDIT : На самом деле этого нельзя сделать с помощью std::advance, посколькуstd::advance не проверяет, выходите ли вы за пределы диапазона.

Ответы [ 2 ]

2 голосов
/ 22 июня 2011

Я не вижу ничего подобного встроенному, но это кажется довольно простым для реализации:

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()
    );
}
0 голосов
/ 21 марта 2018

Я столкнулся с подобной проблемой.Я решил это с помощью boost :: adapter :: strided .

...