【问题标题】:STL function for determining if distance is within `n`用于确定距离是否在“n”内的 STL 函数
【发布时间】:2019-11-09 23:21:04
【问题描述】:

假设我有一些容器 C 元素和两个迭代器 it1it2 (it1 <= it2 wlog) 。如果std::distance(it1, it2) <= n,我想执行一些操作f。此外,it1it2 在一个循环内发生变化(可能是随机变化的),我需要在每次迭代时检查距离。

如果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
}

【问题讨论】:

  • 可能,但对我来说抽象太多而代码太少。请提供minimal reproducible example
  • 现代编译器可能会将std::distance(it1, it2) &lt;= n 优化为类似于非随机访问迭代器的代码。
  • 我提供的函数并不是要对 RAI 进行优化,也不是要断言 it1
  • 你如何/为什么可以假设it1 &lt;= it2 wlog? &lt;= 没有为非随机访问迭代器定义。您可能会遇到这样一种情况,由于某种原因您知道 it1 &lt;= it2,但恕我直言,您不能暗示 w.l.o.g..
  • @Walter 我相信他只是在数学意义上。他断言it1it2 之前。它不会失去一般性,因为如果相反,您可以重新标记它们。

标签: c++ stl iterator containers


【解决方案1】:

据我所知,标准库中没有任何内容可以自动执行此操作。但是,无论如何,您的解决方案都在正确的轨道上成为您想要的。您只需稍作更改,即可使其对随机访问迭代器更有效。

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

【讨论】:

  • 啊,是的,它们都应该是我的工作增量。
  • 不过,不需要变量d。还是没必要。你已经有n了。
  • @Walter 我不这么认为:循环在n 迭代后或a == b 时停止,以先到者为准。
  • @BryceKille 差不多。请记住,递增结束迭代器也是未定义的行为,因此在it1 == it2 的情况下,递增(即使它是后缀)仍会调用未定义的行为。对于随机访问,它可能没问题,但对于前向迭代器,它可能意味着分段错误。
  • @Walter 嗯,我猜。我倾向于避免像那样修改参数,但我想我已经在修改a,所以不如减少n
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-23
  • 1970-01-01
  • 1970-01-01
  • 2023-03-23
  • 1970-01-01
相关资源
最近更新 更多