为什么累积C++定义了两个模板
Why does accumulate in C++ have two templates defined
当工作可以用一个模板(具有binaryOperation
和默认值求和的模板(完成时,为什么累加C++定义了两个模板? 我指的是来自 http://www.cplusplus.com/reference/numeric/accumulate/的累积声明
因为这就是标准的指定方式。
使用重载还是默认参数通常是一个品味问题。在这种情况下,超载被选择(由委员会、亚历山大·斯捷潘诺夫或碰巧负责选择的人(。
默认值比重载更受限制。例如,您可以有一个指向第一个重载的函数指针T (*)(InputIterator, InputIterator, T)
,如果只有一个函数(模板(具有 4 个参数,则这是不可能的。如果可能,这种灵活性可以用作使用重载而不是默认参数的参数。
确实,您会从单个模板中获得几乎相同的行为,例如
template <class InputIt, class T, class BinaryOperation = std::plus<>>
accumulate(InputIt first, InputIt last, T init, BinaryOperation op = {});
但请注意,在早期版本的C++中,这将是困难或不可能的:
- 在 C++11 之前,函数模板不能具有默认模板参数。
- 在 C++14 之前,
std::plus<>
(与std::plus<void>
相同(无效:类模板只能使用一种特定的参数类型实例化。 accumulate
模板甚至比1998年的第一个C++标准还要古老:它可以追溯到SGI STL库。当时,编译器对模板的支持相当不一致,因此建议使模板尽可能简单。
因此,保留了原来的两份声明。正如 bobah 的回答中所指出的,将它们组合成一个声明可能会破坏现有代码,因为例如代码可能使用函数指针指向三参数版本的实例化(并且函数指针不能表示默认函数参数,无论函数是否来自模板(。
有时,标准库会向现有函数添加额外的重载,但通常仅用于改进接口的特定目的,并且在可能的情况下不会破坏旧代码。 没有任何这样的理由std::accumulate
.
(但请注意,标准库中的成员函数可能比非成员函数(如std::accumulate
(更频繁地更改。该标准允许实现声明具有不同重载、默认参数等的成员函数,只要效果如前所述即可。这意味着首先将指向成员函数的指针指向标准库类成员或以其他方式假定非常具体的声明通常是一个坏主意。
这两个函数的动机与我们同时拥有copy
函数和transform
函数的原因相同,以使编码人员能够灵活地在每个元素的基础上应用函数。但也许一些现实世界的代码将有助于理解这将在哪里使用。我在编码中专业地使用了这两个截图:
累积的第一个实例可用于对范围的元素求和。例如,给定const int input[] = { 13, 42 }
我可以这样做来获取input
中所有元素的总和:
accumulate(cbegin(input), cend(input), 0) /* Returns 55 */
我个人最常使用 2nd实例来生成string
s(因为它是 c++ 最接近join
的东西(,但它也可以在添加元素之前需要特殊预处理时使用。例如:
accumulate(next(cbegin(input)), cend(input), to_string(front(input)), [](const auto& current_sum, const auto i){ return current_sum + ", " + to_string(i); }) /* Returns "13, 42"s */
在考虑我使用 2nd函数时,值得注意的是P0616R0。这个提议已经被 c++20 接受,并将移动而不是复制第一个参数到accumulate
的函子中,"可以导致巨大的改进(特别是, 意味着累积string
s是线性的而不是二次的(。
- 如何在C++中从两个单独的for循环中添加两个数组
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 当在同一名称空间中有两个具有相同签名的函数时,会发生什么
- 如何返回一个类的两个对象相加的结果
- 如何在C++中将一个无符号的 int 转换为两个无符号的短裤?
- 如何将两个不同矢量的同一位置的两个元素组合在一起
- 两个字符串在 c++ 中不相等
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 两个文件使用彼此的功能-如何解决
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 如何确保在使用基于布尔值的两个方法之一调用方法时避免分支预测错误
- 停止cmake target_link_libraries将插件中静态库的两个对象文件链接到静态库本身
- 将fold表达式与std::一起用于两个元组
- 如何在C++中比较两个char数组
- 给定两个偶数,求出它们之间所有偶数的平方和
- 比较两个大小不等的映射c++
- C++需要帮助从用户那里获得一个整数,并确保它在另外两个整数之间
- 如何在for循环中包含两个索引值的测试条件
- 在声明中合并两个常量"std::set"(不是在运行时)
- 如何使用OpenMP并行这两个循环