2013-08-16 52 views
3

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

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

这是正确的吗?有一个更好的方法吗?

+0

要检查范围是否有效,请增加第一个迭代器直到它等于第二个;那么你知道它是有效的。如果它不等于第二个,那么范围是无效的。 –

+0

更严重的一点是:不要将范围和容器等同起来。容器是创建范围的一种方式,但它们不是唯一的方法。例如,输入流中的迭代器不是来自容器。 –

+0

@PeteBecker在这种情况下,为什么像'list_a.assign(list_b.end(),list_b.begin());'挂起程序? 'std :: list :: end'和'std :: list :: begin'返回一个双向迭代器,所以第一个迭代器最终会到达第二个迭代器,这意味着它应该根据你的描述是有效的。 – Dennis

回答

7

如何检查范围是否有效?

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

需要注意的是,微软提供了一个函数来检查指针是否有效,并彻底解决了所有使用它的人。雷蒙德表示,它应该被命名为CorruptMemoryIfPossible。

+5

+1 Ha microsoft – aaronman

+0

我发现了Raymond Chen的帖子:http://blogs.msdn.com/b/oldnewthing/archive/2006/09/27/773741.aspx。很好的阅读。 TL; DR在给出无效输入时应该会崩溃。 – Dennis