为什么标准定义end()为结束,而不是实际结束?
end()
最好的论点很容易是Dijkstra 自己提出的论点:
你希望范围的大小是一个简单的差异 end - 捖 - begin ;
当序列退化为空序列时,包括下限更“自然”,并且还因为替代方案( 不包括 下限)需要存在“一个在开始之前”的标记值。
你仍然需要证明为什么你从零开始计数而不是一,但这不是你问题的一部分。
当您有任何类型的算法来处理对基于范围的构造的多个嵌套或迭代调用时,[begin, end) 约定背后的智慧一次又一次地得到回报,这些构造自然地链接在一起。相比之下,使用双重封闭的范围会导致错误和非常不愉快和嘈杂的代码。例如,考虑一个分区 [ n 0 , n 1 )[ n 1 , n 2 )[ n 2 , n 3 )。另一个例子是标准迭代循环for (it = begin; it != end; ++it),它运行end - begin时间。如果两端都是包容性的,那么相应的代码的可读性就会大大降低——想象一下你将如何处理空范围。
for (it = begin; it != end; ++it)
end - begin
最后,我们还可以提出一个很好的论点,为什么计数应该从零开始:根据我们刚刚建立的范围的半开约定,如果给定一个包含 N 个元素的范围(比如枚举数组的成员),那么0 是自然的“开始”,因此您可以将范围写为 [0, N ),而无需任何尴尬的偏移或更正。
简而言之:我们1在基于范围的算法中看不到数字的事实是 [begin, end) 约定的直接结果和动机。
1