Reputation: 738
If I have a template function, say one that calculates an average by summing up the elements in a container of type T holding things of T::value_type, how do I elegantly initialize the sum with a zero?
Suppose the underlying type is not a plain old data type. It could be a complex variable, or some other as yet uncoded mathematical entity which has some form of a zero.
Something more elegant than
T::value_type sum = 0;
Then hoping for the best cast.
Upvotes: 1
Views: 3150
Reputation: 21123
You can either have the user provide the initial 'empty' value or you can take the first element as the initial value, and then perform the addition from the second element on. It results in only using the default constructor if you pass it an empty list. Otherwise, it uses the first element as an initial sum, and goes from there.
template <class Iterator>
typename std::iterator_traits<Iterator>::value_type average_elements(Iterator first, Iterator last) {
typedef typename std::iterator_traits<Iterator>::value_type value_type;
if (first == last) {
return value_type(); // Best you can do
}
value_type sum = *first++;
size_t n = 1;
while (first != last) {
sum += *first++;
++n;
}
return sum / n;
}
Upvotes: 0
Reputation: 361612
typename T::value_type sum = typename T::value_type(); //or simply = 0;
The important point here is : typename
is must. If you don't write it, a Standard-conformant compiler would give compilation error.
Upvotes: 2
Reputation: 58685
Take the initial value as a parameter:
template<typename In, typename T>
T accumulate(In first, In last, T init);
That happens to be the signature of std::accumulate()
from <numeric>
, by the way.
Upvotes: 2