Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does accumulate in C++ have two templates defined

Tags:

c++

Why does accumulate in C++ have two templates defined when the job can be done with just one template (the one with the binaryOperation and default value to sum)? I am referring to the accumulate declaration from http://www.cplusplus.com/reference/numeric/accumulate/

like image 994
NIKESH SINGH Avatar asked Sep 21 '18 11:09

NIKESH SINGH


2 Answers

Because that's how the standard has been specified.

It is often a matter of taste whether to use an overload or a default argument. In this case, overload was chosen (by committee, by Alexander Stepanov, or by whoever happened to be responsible for the choice).

Default values are more limited than overloads. For example, you can have a function pointer T (*)(InputIterator, InputIterator, T) pointing to the first overload, which would not be possible if there was only one function (template) with 4 arguments. This flexibility can be used as an argument for using overloads rather than default arguments when possible.

like image 135
eerorika Avatar answered Oct 23 '22 14:10

eerorika


It's true you would get mostly the same behavior from a single template like

template <class InputIt, class T, class BinaryOperation = std::plus<>>
accumulate(InputIt first, InputIt last, T init, BinaryOperation op = {});

But note that in earlier versions of C++, this would be difficult or impossible:

  • Prior to C++11, a function template could not have default template arguments.
  • Prior to C++14, std::plus<> (which is the same as std::plus<void>) was not valid: the class template could only be instantiated with one specific argument type.
  • The accumulate template is even older than the first C++ Standard of 1998: it goes back to the SGI STL library. At that time, compiler support for templates was rather inconsistent, so it was advisable to keep templates as simple as possible.

So the original two declarations were kept. As noted in bobah's answer, combining them into one declaration could break existing code, since for example code might be using a function pointer to an instantiation of the three-argument version (and function pointers cannot represent a default function argument, whether the function is from a template or not).

Sometimes the Standard library will add additional overloads to an existing function, but usually only for a specific purpose that would improve the interface, and when possible without breaking old code. There hasn't been any such reason for std::accumulate.

(But note member functions in the standard library can change more often than non-member functions like std::accumulate. The Standard gives implementations permission to declare member functions with different overloads, default arguments, etc. than specified as long as the effects are as described. This means it's generally a bad idea to take pointers to member functions to standard library class members, or otherwise assume very specific declarations, in the first place.)

like image 26
aschepler Avatar answered Oct 23 '22 14:10

aschepler