Функция STL для определения, находится ли расстояние в пределах `n` - PullRequest
2 голосов
/ 28 июня 2019

Допустим, у меня есть некоторый контейнер C элементов и два итератора it1 и it2 (it1 <= it2 wlog). Если std::distance(it1, it2) <= n, я хочу выполнить какое-то действие f. Кроме того, it1 и it2 изменяются (возможно, случайным образом) внутри цикла, и мне нужно проверять расстояние при каждой итерации.

Если C очень большой и не произвольный доступ, вызов std::distance на каждой итерации крайне расточителен, поскольку нам нужно только определить, меньше ли расстояние, чем какое-либо n. Довольно просто написать некоторую функцию, которая будет принимать два итератора и целое число и возвращать, находится ли расстояние между ними в пределах предоставленного целого числа, однако мне интересно, есть ли какой-нибудь способ использовать STL для выполнения этой задачи.

По сути, я ищу STL-версию функции ниже:

template <class ForwardIt>
bool is_within(ForwardIt it1, ForwardIt it2, int n) {
  int i = 0;
  while (i++ <= n)
    if (it1++ == it2) return true;
  return false
}

1 Ответ

2 голосов
/ 28 июня 2019

Насколько я знаю, в стандартной библиотеке нет ничего, чтобы сделать это автоматически. Однако ваше решение на правильном пути, чтобы быть тем, что вы хотите в любом случае. Вам нужно лишь небольшое изменение, чтобы сделать его более эффективным для итераторов с произвольным доступом.

template<typename Iter>
bool is_within(Iter a, Iter b, std::size_t n)
{
    // if we're a random access iterator, use the (faster) std::distance() method
    if constexpr (std::is_same_v<typename std::iterator_traits<Iter>::iterator_category, std::random_access_iterator_tag>)
    {
        return std::distance(a, b) <= n;
    }
    // otherwise go the long way around with short circuiting on n
    else
    {
        for (; n > 0 && a != b; --n, ++a);
        return a == b;
    }
}
...