繁体   English   中英

如何检查迭代器指定的范围是否有效?

[英]How to check if a range specified by iterators is valid?

许多标准库容器具有接受迭代器指定范围的操作。 例如, std::list::assign(InputIterator first, InputIterator last)

但是因为很多这些操作都不会抛出异常,如果[first,last)指定的范围无效,就会导致未定义的行为。

那么什么有效范围? 我认为这意味着容器中first出现在或等于last之前,因为当我尝试其他方式时(即first出现在last之后),程序的执行将挂起。

例如:

std::list.assign(container.begin(), container.end()); // valid range
std::list.assign(container.end(), container.begin()); // invalid range

现在假设有效范围是什么,我们如何检查范围是否有效?

我想出了一个辅助函数,它在到达容器末尾之前检查first是否等于last 如果为真,则有力保证first不会在last之后出现,因此范围是有效的。

template <typename Iterator>
bool isValidRange(Iterator first, Iterator last, Iterator end)
{
  for (; first != end; ++first)
    if (first == last) return true;
  return false;
}

这不是很方便,因为除了指定范围的迭代器之外,您还必须将迭代器传递给容器的末尾。

这个对吗? 有一个更好的方法吗?

我们如何检查范围是否有效?

你不能。 您的函数不能保证范围有效,只能从最后一个可以到达。 这是两个不同的事情(对于一个简单的例子,考虑将迭代器转换为随后重新分配的向量)。 标准没有允许您检查范围是否有效的机制。 就像你在取消引用之前无法知道指针有效一样。

需要注意的是,Microsoft提供了一个函数来检查指针是否有效,并且完全搞砸了使用它的每个人。 雷蒙德陈说它应该被命名为CorruptMemoryIfPossible。

[iterator.requirements.general]定义了“有效范围”术语:

10 当且仅当存在使 i == s 的表达式 ++i 的有限应用序列时,才称哨兵 s 从迭代器 i 可达。 如果 s 可以从 i 到达,则 [i, s) 表示有效范围。

因此,“从第一个开始就可以到达最后一个”完全等于标准 PoV 中的“有效范围”定义(因此对于 UB 定义)。 迭代器的可解引用性与此定义正交。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM