October 27th, 2005, 7:21 am
Ckarakus,I knew you were good.Almost correct, but there's a glitch in your solution and one in my question (note: I'm referring to your first solution, as I wrote the rest of this post before you contributed your second one.)The glitch in my question is that I didn't specify the interface of the iterator-taking function. There were three alternatives.The first is your solution, taking two iterators and n.The second isaverage(InputIt begin, std::size_t n);since we can just start from begin and increment n times, leaving it to client code to enforce bound-checking.The third isaverage(InputIn begin, InputIt end);since one can limit the average to n elements by writing, e.g.,std::vector<double> v(...);average(v.begin(), v.begin()+n);I admit that the third was what I had in mind (and was the one that could be written using STL functions, namely,average(begin, end) <-> std::accumulate(begin,end,value_type())/std:istance(begin,end)sorry to have put you on a wrong track.) but on second thought it has serious drawbacks. One is that the above can be done with lists, as in std::list<double> l(...);average(l.begin(), std::advance(l.begin(), n));but it is not efficient, as one would traverse the list twice (one inside std::advance and one while collecting the values.) The same applies to accumulate & distance; and for the same reason, one would need at least forward iterators as input iterators might not be read twice.The glitch in your solution is the check for i != end. On the one hand, it is good to check that we don't dereference an off-the-end iterator as it would cause undefined behavior. But on the other hand, if the iterator reach the end your code just ends the loop silently, which gives the client code a result but no hint that anything went wrong. For instance, vector<double> v(2);v[0] = 1;v[1] = 5;double x = average(v.begin(),v.end(),3);returns (1+5)/3 = 2. It might be better to raise an exception if it == end.The solution is otherwise correct---and with the added touch of using iterator_traits so that it works with built-in arrays as well.Luigi