Why do STL numerical algorithms use "op" rather than "op ="?

Why do std::numeric algorithms prefer op over op = ? For example, here is the implementation of std::accumulate in LLVM:

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

Wouldn't it be potentially more efficient / less verbose / better if implemented using the += operator?

+8
c ++ stl
source share
5 answers

It is defined as in the standard ...

The standard is defined in terms of + , not += :

26.7.2 Accumulation

 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: calculates its result, initializing the accumulator acc with the initial value of init , and then modifies it with acc = acc + *i or cc = binary_op(acc, *i) for each iterator i in the range [first,last) in order.

The same is true for other numerical algorithms.

... and the standard is based on STL ...

But the reason is that they are implemented as they are now. However, to find out about the original reason, you need to go further down the rabbit hole :

Type Requirements

For the first version, which takes two arguments:

  • InputIterator is an input iterator model.
  • T is an Assignable model.
  • If x is an object of type T and y is an object of type InputIterator value , then x + y defined.
  • The return type x + y can be converted to T

... and STL was created using ...?

So why? Let's ask Alexander Stepanov, mind behind the STL:

User

[A] asked [question] on StackOverflow two days ago regarding the implementation and formulation of numerical algorithms such as accumulate or inner_product , which are defined in terms of + instead of += (section 26.7 in ISO C ++ 11).

I tried to find some justification for the solution, but even the version on the SGI page does not mention anything about this particular operator choice.

Was there a choice of operator (a = a + b instead of a + = b) only based on your personal preferences, as some comments suggest? Was + b a more natural way to write an operation then? Or was it just a matter of symmetry between a = a + b and a = bin_op (a, b)?

- [Zeta]

Now, before you read his answer, remember that he started writing a family library about 30 years ago, and his original document and his Maine Lee The Standard This October will be twenty years in the Template Library. Without further ado, I submit his answer:

I suspect this is a symmetry issue between a = a + b and a = bin_op (a, b), but I really don't remember. I should have written a valid document stating all the arguments between the various design options in STL, but I did not. Unfortunately.

(If Stepanov reads this by accident: thanks again for your reply!)

I personally believe that the inspiration of Common Lisp reduce was another factor, but this is just an assumption.

What can be learned from this?

Sometimes the decision in the standard is based on personal preferences and elegance. For example, if Straustup wrote STL, he would "strongly prefer to use" + = b "as a more direct expression of intent and usually faster than a = a + b". However, I must admit that the symmetry between a = a + b and a = bin_op (a, b) has its own beauty.

Considering that this contradiction a+=b and a=a+b will contribute to the challenges:

This problem will become very important when we define standard concepts, and I do not know how this will be resolved. [Straustrup; also thanks to him for answering my question!]

Well, I hope you enjoyed the C ++ story.

+15
source share

This may be more efficient and clearly less verbose.

A common reason for this is to minimize the requirements for the base type. If you used += , then the base type would have to support += . For something like int , which is trivial and already present, but for the class that you define, it is quite possible to define + and = , but not the connection += (in this case, the code that used += obviously not work).

+10
source share

In my opinion, the main reason is that you can use the standard function object std::plus and get the same result as with operator + , in the same way as using operator < and the standard function object std::less in sorting algorithms such as std::sort .

+1
source share

There are many reasons to use + instead of + =.

but. Because it is the right way. Accumulate is fold , a functor (a function that maps functions to functions) that works on +, not + =. Why + instead of + =? Because + = is not a mathematical function.

V. It is more efficient (on modern compilers, on all primitive types and well-designed objects). + = can be faster for compilers 30 years ago, but + faster if only what you accumulate is a monstrous object with too much OO. An analysis of the life cycle of an object is easier to perform on const objects, rather than links.

C. This is clearer. This reason is not significantly different from (A). + is clearer than + =. Brightness trumps verbosity.

0
source share

True, I think this is reuse. The rest of the STL uses binary operators, and += action. So plus , multiplies , etc., but not add_action (say). Operators and actions are completely symmetrical, but if you implement more than 90 algorithms, at some point you may have to stop adding new concepts and submit them.

Alex said he never planned for his STL to be the end of all STL development, especially. since the standardized version contains only a small part of what he originally offered. This is an obvious extension.

0
source share

All Articles