简体   繁体   English

为什么STL数值算法使用'op'而不是'op ='?

[英]Why do STL numeric algorithms use 'op' rather than 'op='?

Why do std::numeric algorithms seem to prefer op instead of op= ? 为什么std::numeric算法似乎更喜欢op而不是op = For example, here is the implementation of std::accumulate in LLVM: 例如,以下是LLVM中std::accumulate的实现:

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;
}

Would this not be potentially more efficient/less verbose/better if implemented using the += operator? 如果使用+=运算符实现,这不会更有效/更简洁/更好吗?

It is defined like this in the standard… 它在标准中定义如下......

The standard is defined in terms of + , not += : 标准用+ ,而不是+=

26.7.2 Accumulate [accumulate] 26.7.2累积[accumulate]

 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); 

Effects: Computes its result by initializing the accumulator acc with the initial value init and then modifies it with acc = acc + *i or a cc = binary_op(acc, *i) for every iterator i in the range [first,last) in order. 效果:通过初始化累加器acc初始值init计算其结果,然后使用acc = acc + *icc = binary_op(acc, *i)[first,last)范围内的每个迭代器i修改它的结果。订购。

Same holds for other numerical algorithms. 其他数值算法也是如此。

…and the standard is based on STL… ......而标准是基于STL ......

But that's the reason why they're implemented like this nowadays. 但这就是为什么他们现在这样实施的原因。 However, to learn about the original reason, one needs to go further down the rabbit hole : 但是,要了解原因,需要进一步深入兔子洞

Requirements on types 对类型的要求

For the first version, the one that takes two arguments: 对于第一个版本,带有两个参数的版本:

  • InputIterator is a model of Input Iterator. InputIterator是Input Iterator的模型。
  • T is a model of Assignable. T是可分配的模型。
  • If x is an object of type T and y is an object of InputIterator 's value type, then x + y is defined. 如果xT类型的对象, yInputIteratorvalue类型的对象,则定义x + y
  • The return type of x + y is convertible to T . x + y的返回类型可转换为T

…and the STL has been created by…? ......而STL是由...创建的?

So, why is that? 那么,为什么呢? Lets ask Alexander Stepanov, the mind behind STL: 让我们问一下STL背后的思想亚历山大斯蒂芬诺夫:

[A] user has asked a [question] on StackOverflow two days ago concerning the implementation and formulation of numerical algorithms like accumulate or inner_product , which are defined in terms of + instead of += (section 26.7 in ISO C++11). [A]用户两天前在StackOverflow上询问[问题]关于数字算法(如accumulateinner_product的实现和制定,这些算法是用+而不是+= (ISO C ++ 11中的第26.7节)。

I've tried to find some rationale behind the decision, but even the version on SGI's page doesn't mention anything regarding this particular choice of the operator. 我试图找到决定背后的一些理由,但即使是SGI页面上的版本也未提及有关此特定运算符选择的任何内容。

Was the choice of the operator (a = a + b instead of a += b) only based on your personal preference, as some comments assume? 是否根据您的个人偏好选择了运营商(a = a + b而不是+ = b),正如一些评论所假设的那样? Was a+b the more natural way to write the operation back then? 当然,+ b是更自然的编写操作的方式吗? Or was it simply a matter of symmetry between a = a +b and a = bin_op(a,b)? 或者只是a = a + b和a = bin_op(a,b)之间的对称问题?

-- [Zeta] - [Zeta]

Now, before you read his answer, remember that he started to write a generic library about ~30 years ago, and his and Meng Lee's initial document The Standard Template Library will have its twenty years anniversary this October. 现在,在你阅读他的答案之前,请记住他大约30年前开始写一个通用的图书馆,他和孟李的初始文件标准模板图书馆将在今年10月成立二十周年。 Without further ado, I present his answer: 不用多说,我提出他的答案:

I suspect that it was a matter of symmetry between a = a + b and a = bin_op(a,b), but I really do not remember. 我怀疑这是a = a + b和a = bin_op(a,b)之间的对称问题,但我真的不记得了。 I should have written a rationale document stating all the reasoning between different design choices in STL, but I did not. 我应该写一份理由文件,说明STL中不同设计选择之间的所有推理,但我没有。 Sorry. 抱歉。

(If Stepanov reads this by any chance: thanks again for your answer!) (如果斯捷潘诺夫有机会读到这个:再次感谢你的回答!)

I personally believe that the inspiration by Common Lisp's reduce has been another factor, but that's just speculation. 个人认为Common Lisp reduce的灵感是另一个因素,但这只是猜测。

What can one learn from this? 从中可以学到什么?

Sometimes, decision in a standard are based on personal preference and elegance. 有时,标准中的决定是基于个人偏好和优雅。 For example, if Stroustrup had written the STL, he would have "strongly prefer[ed] the use of a+=b as being a more direct expression of intent and typically faster than a=a+b". 例如,如果Stroustrup写了STL,他就会“非常喜欢使用+ = b作为更直接的意图表达,通常比a = a + b更快”。 However, I have to admit that the symmetry between a = a+b and a=bin_op(a,b) has its own beauty. 但是,我不得不承认a = a + b和a = bin_op(a,b)之间的对称性有其自身的美感。

That being said, this a+=b and a=a+b controversy will promote challenges: 话虽如此,这个a+=ba=a+b争议将会带来挑战:

This issue will become very important when we define standard concepts, and I do not know how it will be resolved. 当我们定义标准概念时,这个问题将变得非常重要,我不知道如何解决它。 [Stroustrup; [Stroustrup的; also thanks to him for answering my question!] 还要感谢他回答我的问题!]

That's all, I hope you've enjoyed the ride through a little bit of C++ history. 就是这样,我希望你能享受到C ++历史的一点点。

It might be more efficient, and would clearly be less verbose. 它可能更有效率,而且显然不那么冗长。

The usual reason for doing things this way is to minimize the requirements on the underlying type. 以这种方式执行操作的通常原因是最小化对底层类型的要求。 If you used += , then the underlying type would have to support += . 如果使用+= ,则基础类型必须支持+= For something like int that's trivial and already present, but for a class you define, it's entirely possible would define + and = , but not the compound += (in which case, code that used += would obviously fail). 对于像int这样简单且已经存在的东西,但对于你定义的类,完全有可能定义+= ,而不是复合+= (在这种情况下,使用+=代码显然会失败)。

在我看来,主要原因是你可以使用标准功能对象std::plus并获得与operator +相同的结果,就像在std::sort等排序算法中使用operator <和标准功能对象std::less一样。

There are plenty of reasons for using + instead of +=. 使用+而不是+ =有很多原因。

A. Because it is the correct way. 答:因为这是正确的方法。 Accumulate is fold , a functor (a function that maps functions to functions) that operates on +, not +=. Accumulate是fold ,一个函数(将函数映射到函数的函数),它在+上运行,而不是+ =。 Why + instead of +=? 为什么+而不是+ =? Because += is not a mathematical function. 因为+ =不是数学函数。

B. It is more efficient (on modern compilers, on all primitive types and well-designed objects). B.它更有效(在现代编译器上,在所有原始类型和精心设计的对象上)。 += might be faster for compilers 30 years ago, but + is faster now, unless what you are accumulating is a monstrous object with too much OO. + = 30年​​前编译器可能会更快,但现在+更快,除非你积累的是一个具有太多OO的怪异对象。 Object lifetime analysis is easier done on const objects rather than references. 对象生命周期分析在const对象而不是引用上更容易完成。

C. It is clearer. C.更清楚。 This reason is really not substantially different from (A). 这个原因与(A)没有实质性的不同。 + is clearer than +=. +比+ =更清晰。 Clarity trumps verbosity. 清晰度胜过冗长。

The truth, I guess, is reuse. 我想,事实是重复使用。 The rest of the STL is using binary operators while += is an action . STL的其余部分使用二元运算符,+=是一个动作 So there's plus , multiplies , etc, but no add_action (say). 所以有plusmultiplies等,但没有add_action (比方说)。 Operators and actions are completely symmetric, but if you implement more than 90 algorithms, at some point you'll probably have to stop adding new concepts and Ship It. 操作符和操作是完全对称的,但如果您实现了90多种算法,那么在某些时候您可能不得不停止添加新概念并发送它。

Alex has said that he never intended for his STL to be the end of all STL development, esp. Alex已经表示他从未打算让他的STL成为所有STL开发的终结,尤其是。 since the standardized version contains only a fraction of what he originally proposed. 因为标准化版本只包含他最初提出的一小部分。 This is an obvious extension. 这是一个明显的扩展。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM