2

标准 ISO C++ 具有丰富的算法库,包括大量的语法糖,如std::max_element, std::fill,std::count等。

我很难理解为什么 ISO 认为适合标准化许多此类琐碎的算法,而不是在整个容器上运行的算法的重载。

我真的不明白为什么当我们没有完整的容器版本(当然是迄今为止最常见的情况)或者类似地留下向量擦除-删除成语的暴行时,他们为什么要添加这些基本的东西:

v.erase(std::remove(v.begin(), v.end(), elem), v.end());

似乎我用 C++ 编写的每个项目,最终都会包含我自己的自定义头文件,其中包含类似这样的基本语法糖。

当然,任何微不足道的整个容器重载都可以包含在自定义标头中。许多标准化的简单算法也是如此。

我试图理解的是为什么标准中的事物有充分的理由,比如std::max_elementstd::fill范围,而不是在整个容器上运行的版本,或者其他减少编写 C++ 代码冗长的语法糖。

4

2 回答 2

4

为什么 C++ 没有标准化在整个容器上运行的算法重载?

答案与对所有此类问题的回答相同:此类重载尚未标准化,因为尚未提出此类更改或尚未接受此类提议。最初的 STL 没有这样的重载。

一个类似问题的答案链接到博客文章,该文章有一个论点,说明为什么这种重载对于某些算法会有问题,这可能是这种重载不是原始设计的一部分,也不是后来引入的部分原因。简而言之,它们会引入歧义和误导性错误消息。


std::ranges然而,自 C++20 以来,C++ 没有重载,而是在单独的命名空间中对完整范围具有相同的算法。使用填充的示例:

std::ranges::fill(container, value);

暴行是向量擦除删除成语

尽管范围没有引入新的成员函数重载,但有一个非成员替代方法用于擦除:

std::erase(vector, elem);
于 2020-11-19T20:55:46.143 回答
4

这已在 C++20 中得到纠正

请参阅有关cppreference的一个示例

template< ranges::input_range R, class Proj = std::identity,
          std::indirect_unary_predicate<std::projected<ranges::iterator_t<R>, Proj>> Pred >
constexpr ranges::range_difference_t<R>
  count_if( R&& r, Pred pred = {}, Proj proj = {} );

bool is_even(int n) {
   return (n % 2 == 0);
}
std::vector<int> l(10);
std::iota(l.begin(), l.end(), 0); // is in numerics which hasn't been rangified.

auto cnt = std::ranges::count_if(arr, is_even);

于 2020-11-19T20:51:26.880 回答