Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/.htaccess/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么STL数值算法使用';op&x27;而不是';op=';?_C++_Stl - Fatal编程技术网

C++ 为什么STL数值算法使用';op&x27;而不是';op=';?

C++ 为什么STL数值算法使用';op&x27;而不是';op=';?,c++,stl,C++,Stl,为什么std::numeric算法似乎更喜欢op而不是op=?例如,以下是在LLVM中实现的std::acculate: template <class _InputIterator, class _Tp> inline _LIBCPP_INLINE_VISIBILITY _Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init) { for (; __first != __last; +

为什么
std::numeric
算法似乎更喜欢op而不是op=?例如,以下是在LLVM中实现的
std::acculate

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;
}
模板
内联\u LIBCPP\u内联\u可见性
_总磷
累加(\u inputierator\u first,\u inputierator\u last,\u Tp\u init)
{
对于(;\uuuu first!=\uuuu last;++\uuu first)
__init=uuu init+*uuu first;
返回初始化;
}

如果使用
+=
操作符来实现,这不是可能更高效/更简洁/更好吗?

它可能更高效,而且显然更简洁


这样做的通常原因是最小化对底层类型的需求。如果使用了
+=
,则基础类型必须支持
+=
。对于像
int
这样的简单且已经存在的类,但是对于您定义的类,完全可以定义
+
=
,但不能定义复合的
+=
(在这种情况下,使用
+=
的代码显然会失败).

在我看来,主要原因是您可以使用标准函数对象
std::plus
,并获得与
运算符+
相同的结果,就像使用
运算符一样,在标准中定义为这样…
本标准是根据
+
而不是
+=
定义的:

26.7.2累计
[累计]
模板
T累计(先输入计数器,后输入计数器,T初始化);
模板
T累计(先输入计数器,后输入计数器,T初始化,
二进制操作(二进制操作);
效果:使用初始值
init
初始化累加器
acc
,然后使用范围内的每个迭代器
acc=acc+*i
或a
cc=binary_op(acc,*i)
修改累加器,从而计算其结果
[第一个,最后一个)
按顺序排列

其他数值算法也是如此

…该标准基于STL… 但这就是为什么它们现在会这样实施的原因。然而,要了解最初的原因,需要:

对类型的要求 对于第一个版本,采用两个参数的版本:

  • inputierator
    是输入迭代器的一个模型
  • T
    是一种可分配的模型
  • 如果
    x
    T
    类型的对象,
    y
    inputierator
    值的
    类型的对象,则定义
    x+y
  • x+y
    的返回类型可转换为
    T
…STL是由…创建的…? 那么,这是为什么呢?让我们问问亚历山大·斯捷潘诺夫,STL背后的思想:

[A] 用户在两天前就StackOverflow提出了一个关于 数值算法的实现和公式,如
累积
内部产品
,根据
+
而不是
+=
(ISO C++11中的第26.7节)

我试图找到这个决定背后的一些理由,但即使是 SGI页面上的版本没有提及任何与此相关的内容 操作员的特殊选择

是否仅选择运算符(a=a+b而不是a+=b) 根据你的个人喜好,正如一些评论所假设的那样?是a+b 当时写操作的更自然的方式是什么 仅仅是a=a+b和a=bin_op(a,b)之间的对称问题

--[泽塔]

现在,在你阅读他的答案之前,请记住,他大约在30年前开始编写一个通用库,他和李蒙的初始文档将在今年10月迎来20周年纪念日。我毫不犹豫地给出他的答案:

我怀疑这是a=a+b和a=bin_op(a,b)之间的对称性问题,但我真的不记得了。我应该写一份基本原理文档,说明STL中不同设计选择之间的所有推理,但我没有。对不起

(如果斯捷潘诺夫偶然读到这篇文章:再次感谢你的回答!)

我个人认为Common Lisp的
reduce
的灵感是另一个因素,但这只是猜测

从中我们可以学到什么? 有时,标准中的决定是基于个人偏好和优雅。例如,如果斯特劳斯特鲁普编写了STL,他会“强烈倾向于使用a+=b作为更直接的意图表达,通常比a=a+b更快”。然而,我不得不承认,a=a+b和a=bin_op(a,b)之间的对称性有它自己的美

这就是说,这场
a+=b
a=a+b
争议将引发挑战:

当我们定义标准概念时,这个问题将变得非常重要,我不知道它将如何解决。[Stroustrup;也感谢他回答我的问题!]


这就是全部,我希望你喜欢通过一点点C++历史。

使用+ +而不是+= ./p>有很多原因。 A.因为这是正确的方法,一个函子(一个将函数映射到函数的函数)在+,而不是+=。为什么+而不是+=?因为+=不是一个数学函数

B.它更高效(在现代编译器上,在所有基本类型和精心设计的对象上)。+=对于30年前的编译器来说可能更快,但是现在+更快,除非你积累的是一个有太多OO的怪物对象。对象生命周期分析更容易在常量对象上完成,而不是在引用上完成


C.更清晰。这个原因实际上与(A)没有本质上的区别。+比+=。清晰胜过冗长。

我想,事实是重用。STL的其余部分使用二进制运算符,而
+=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);