5

许多标准库容器具有接受迭代器指定范围的操作。例如,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;
}

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

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

4

2 回答 2

7

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

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

需要注意的是,微软提供了一个检查指针是否有效的功能,它彻底搞砸了所有使用它的人。Raymond Chen 说它应该被命名为 CorruptMemoryIfPossible。

于 2013-08-16T05:26:53.753 回答
0

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

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

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

于 2022-01-13T07:17:26.477 回答