Generic mean function It seems useful to have a generic function to calculate the mean of all elements in a container, so I wrote one. By default it calculates the arithmetic mean, but should be able to accommodate other means (like geometric) if passed the appropriate functors.

Assumptions:


value_type can be default-constructed to yield a "zero-value" of its type


I am particularly interested in feedback on:


The validity of my assumptions
The mean() interface
How I validate my iterators
General code style.


mean.hpp

#ifndef MEAN_HPP
#define MEAN_HPP

#include &lt;algorithm&gt;
#include &lt;functional&gt;
#include &lt;iterator&gt;
#include &lt;numeric&gt;
#include &lt;type_traits&gt;

template &lt;class ForwardIt, class DivOp = std::divides&lt;&gt;, class AddOp = std::plus&lt;&gt;,
          class = std::enable_if_t&lt;
                  std::is_base_of&lt;
                  std::forward_iterator_tag,
                  typename std::iterator_traits&lt;ForwardIt&gt;::iterator_category&gt;::value&gt;&gt;
typename std::iterator_traits&lt;ForwardIt&gt;::value_type mean(ForwardIt begin,
                                                          ForwardIt end,
                                                          DivOp div = DivOp(),
                                                          AddOp add = AddOp())
{
    using value_type = typename std::iterator_traits&lt;ForwardIt&gt;::value_type;
    const auto sum = std::accumulate(begin, end, value_type(), add);
    const auto count = std::distance(begin, end);
    return div(sum, count);
}

#endif


Below is included some example code to demonstrate the usage of mean(). I'm less interested in feedback on the example code, but it is of course still welcome.

main.cpp

#include "mean.hpp"
#include &lt;iostream&gt;
#include &lt;vector&gt;

struct Point
{
    Point() : x(0), y(0) {}
    Point(int x, int y) : x(x), y(y) {}

    int x, y;
};

Point operator+ (const Point&amp; lhs, const Point&amp; rhs)
{
    return Point(lhs.x + rhs.x, lhs.y + rhs.y);
}

int main()
{
    // Works on primitives
    const std::vector&lt;float&gt; scalars{1, 2, 3, 4, 5, 6, 7, 8, 9};
    const auto scalarResult = mean(scalars.begin(), scalars.end());
    std::cout &lt;&lt; scalarResult &lt;&lt; std::endl;

    // Works on class types with appropriate operators
    const std::vector&lt;Point&gt; points{{1,1}, {2,2}, {3,3}};
    const auto pointDivision = [] (const Point&amp; sum, const float count)
    {
        return Point(sum.x / count, sum.y / count);
    };
    const auto pointResult = mean(points.begin(), points.end(), pointDivision);
    std::cout &lt;&lt; pointResult.x &lt;&lt; " " &lt;&lt; pointResult.y &lt;&lt; std::endl;
}
The arithmetic mean is not necessarily a closed operation: the mean of integers is, in general, not an integer.  Therefore, you should provide a specialization of the template for integer inputs.