Rather than doing editing to assure that your iterators refer to lists of the same type, you'd be much better off writing the code as a generic algorithm with the iterator type as a template parameter.
I'd also note that for std::list
, both your original code and most of the posted answers have a rather serious efficiency problem: given a typical implementation of list, they iterate through the list once to add up the values, and then do it again to count the number of elements. In theory, list.size()
could run in constant time without iterating through the elements, but in fact that's rarely the case (you can have constant complexity for list::size()
or list::splice
, but not for both at once).
I'd write the code something like:
template <class fwdit>
typename fwdit::value_type arithmetic_mean(fwdit begin, fwdit end) {
typedef typename fwdit::value_type res_type;
res_type sum = res_type();
size_t count = 0;
for (fwdit pos = begin; pos!= end; ++pos) {
sum += *pos;
++count;
}
return sum/count;
}
This is generic, so it'll continue to work (unaltered) when you realize that std::list
was a poor choice, and you'd really be better off with std::vector
. Likewise, if you want the arithmetic mean of some int's instead of double's, it can handle that as well (again, without changing the code). Third, even if (as suggested above) your library's implementation of st::list::size()
happens to be linear, this still only traverses the list once, so it's likely to be around twice as fast as (a working version of) the original code.
Of course, caching can (will) affect that -- when you average a small list, the first traversal will pull the whole list into the cache, so the second traversal will usually be a lot faster (so eliminating that second traversal won't save as much time).