为什么std::numeric算法似乎更喜欢op而不是op =?例如,以下是std::accumulateLLVM中的实现:
template <class _InputIterator, class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
_Tp
accumulate(_InputIterator __first, _InputIterator __last, _Tp __init)
{
for (; __first != __last; ++__first)
__init = __init + *__first;
return __init;
}
Run Code Online (Sandbox Code Playgroud)
如果使用+=运营商实施,这不会更有效/更简洁/更好吗?
Zet*_*eta 15
标准是根据而+不是+=:
26.7.2累积
[accumulate]Run Code Online (Sandbox Code Playgroud)template <class InputIterator, class T> T accumulate(InputIterator first, InputIterator last, T init); template <class InputIterator, class T, class BinaryOperation> T accumulate(InputIterator first, InputIterator last, T init, BinaryOperation binary_op);效果:通过
acc使用初始值初始化累加器来计算其结果init,然后使用acc = acc + *i或按顺序修改范围内的cc = binary_op(acc, *i)每个迭代器.i[first,last)
其他数值算法也是如此.
但这就是为什么他们现在这样实施的原因.但是,要了解原因,需要进一步深入兔子洞:
对类型的要求
对于第一个版本,带有两个参数的版本:
InputIterator是输入迭代器的模型.T是可分配的模型.- 如果
x是类型的对象T和y是的目的InputIterator的value类型,那么x + y被定义.- 返回类型
x + y可转换为T.
那么,为什么呢?让我们问一下STL背后的思想亚历山大斯蒂芬诺夫:
[A]用户已经要求一个[问题]在计算器上两天前有关的像数值算法的实现和制剂
accumulate或inner_product,它们在以下方面所定义+的,而不是+=(在ISO C++ 11 26.7节).我试图找到决定背后的一些理由,但即使是SGI页面上的版本也未提及有关此特定运算符选择的任何内容.
是否根据您的个人偏好选择了运营商(a = a + b而不是+ = b),正如一些评论所假设的那样?当然,+ b是更自然的编写操作的方式吗?或者只是a = a + b和a = bin_op(a,b)之间的对称问题?
- [Zeta]
现在,在你阅读他的答案之前,请记住他大约30年前开始写一个通用的图书馆,他和孟李的初始文件标准模板图书馆将在今年10月成立二十周年.不用多说,我提出他的答案:
我怀疑这是a = a + b和a = bin_op(a,b)之间的对称问题,但我真的不记得了.我应该写一份理由文件,说明STL中不同设计选择之间的所有推理,但我没有.抱歉.
(如果斯捷潘诺夫有机会读到这个:再次感谢你的回答!)
我个人认为Common Lisp的灵感reduce是另一个因素,但这只是猜测.
有时,标准中的决定是基于个人偏好和优雅.例如,如果Stroustrup写了STL,他就会"非常喜欢使用+ = b作为更直接的意图表达,通常比a = a + b更快".但是,我不得不承认a = a + b和a = bin_op(a,b)之间的对称性有其自身的美感.
话虽这么说,这个a+=b和a=a+b争议将促进挑战:
当我们定义标准概念时,这个问题将变得非常重要,我不知道如何解决它.[Stroustrup的; 还要感谢他回答我的问题!]
就是这样,我希望你能享受到C++历史的一点点.
Jer*_*fin 10
它可能更有效率,而且显然不那么冗长.
这种方式的通常原因是最小化对底层类型的要求.如果您使用过+=,则基础类型必须支持+=.对于类似的东西int那是微不足道的,并且已经存在,但你定义一个类,它完全有可能将定义+和=,而不是化合物+=(在这种情况下,代码使用+=显然会失败).