为什么std::range::sort
(和其他基于范围的算法)在range
命名空间中实现?为什么不将其定义为std::sort
取值范围的超载?
1 回答
这是为了避免破坏现有的代码库。Eric Niebler、Sean Parent 和 Andrew Sutton 在他们的设计论文D4128中讨论了不同的方法。
3.3.6 更改算法返回类型以适应哨兵
...以类似的方式,大多数算法在泛化以支持哨兵时都会获得新的返回类型。在许多情况下,这是一个破坏源的变化。在某些情况下,例如
for_each
,更改不太可能具有很大的破坏性。在其他情况下,情况可能更是如此。仅仅接受破损显然是不可接受的。我们可以想象三种方法来缓解这个问题:
仅当迭代器和哨兵的类型不同时才更改返回类型。这会导致界面稍微复杂一些,可能会使用户感到困惑。它还使通用代码变得非常复杂,这需要元编程逻辑才能使用调用某些算法的结果。因此,这里不探讨这种可能性。
使算法的新返回类型隐式转换为旧返回类型。考虑
copy
,它当前返回输出迭代器的结束位置。当更改以适应哨兵时,返回类型将更改为类似的东西pair<I, O>;
,即一对输入和输出迭代器。pair
我们可以返回一种可以隐式转换为其第二个参数的对,而不是返回 a 。这避免了在某些(但不是全部)场景中的损坏。这种诡计不太可能完全被忽视。在用户必须选择加入的单独命名空间中交付新标准库。在这种情况下,除非用户明确移植他们的代码,否则不会破坏任何代码。然后,用户必须适应更改的返回类型。类似于 clang modernize 的自动升级工具在这里可以提供很大帮助。
我们,作者,更喜欢(3)。
最终,它对使用支持 C++20 的编译器进行构建的现有代码库的破坏性最小。这是他们自己喜欢的方法,其余的似乎都是历史。