I'm currently learning C++ using the book "Accelerated C++", working through many of the exercises at the end of each chapter. One particular exercise at the end of chapter 10 asks you to rewrite the following template function so it can be called with any container which supports random access iterators, rather than just STL vectors:
template <class T>
T median(vector<T> v)
{
typedef typename vector<T>::size_type vec_sz;
vec_sz size = v.size();
if (size == 0)
throw domain_error("median of an empty vector");
sort(v.begin(), v.end());
vec_sz mid = size/2;
return size % 2 == 0 ? (v[mid] + v[mid-1]) / 2 : v[mid];
}
My solution is as follows:
template <class T, class Ran>
T median(Ran begin, Ran end)
{
typename typedef vector<T>::size_type vec_sz;
if (begin == end)
throw domain_error("median of an empty vector");
// Copy all elements from begin to end-1 to a new vector
vector<T> v(begin, end);
vec_sz size = v.size();
vec_sz mid = size/2;
sort(v.begin(), v.end());
return size % 2 == 0 ? (v[mid] + v[mid-1]) / 2 : v[mid];
}
When calling this function, I need to type median<double>(begin, end), where begin and end are random access iterators on a container. My question is, is there any way to just call median(begin, end)? Right now, if I try that, my code won't compile (I'm guessing this is because the compiler has no way of knowing what type T is). Is there a better way of solving this problem that I've missed?