C++ 标准是否对在空容器上运行的算法有任何保证?

Does the C++ standard guarantee anything about algorithms operating on empty containers?

例如,

#include <algorithm>
#include <iostream>
#include <numeric>
#include <vector>

int main() {
  std::vector<int> empty{};
  std::reverse(empty.begin(), empty.end());
  std::cout << "Sum: " << std::accumulate(empty.cbegin(), empty.cend(), 0) << std::endl;
  std::cout << empty.size();
}

按我的预期构建和运行:

sum: 0
size: 0

我能保证这种行为会发生在任何符合标准的编译器上吗?

由于标准库算法在迭代器范围上运行,算法保证在传递给它们的任何有效迭代器范围上都是安全有效的.现在我们只需要关心有效的迭代器范围代表什么。

对形成迭代器范围的迭代器的要求:

  • 它们必须引用元素(或最后一个元素之后的元素) 同一个容器
  • 可以通过重复递增begin达到end。在 换句话说,end 不能在 begin.
  • 之前

满足这些要求后,我们可以将任何有效范围视为左包含范围[begin, end)。那么该范围具有以下属性:

  • 如果being等于end,范围为空
  • 如果 begin 不等于 end,则至少有一个元素 范围,being 指的是第一个元素
  • 所以,我们可以增加begin一些次数,直到begin == end (发生这种情况时,范围仍然有效)

正是这些属性为迭代器的便捷使用提供了支持。 <algorithms> 内部结构也基于这些属性。

我们必须知道编译器无法强化这些要求,我们要确保传递范围的有效性(有时有相当多的需要考虑的几个因素).

所以,是的,当传递给算法时,begin == end 仍然是一个有效范围,所以我们得到的输出也是有效的。