template for an array and a vector

U

utab

Dear all,

How can I make a template function to work both with an array and a
vector such as:

template <class T>
T median(vector<T> v)
{
typedef typename std::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];
}

Best,
Umut
 
U

utab

How can I make a template function to work both with an array and a
vector such as:
template<class T>
T median(vector<T>  v)
{
typedef typename std::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];
}

I would probably change your 'median' to accept a pair of
const_iterators (start and end).  Then you can initialize a local vector
with them and do exactly like you do with your 'v' argument.  When you
call it for a vector, you do

     median(myvector.begin(), myvector.end())

and for an array you do

     median(array, array + size_of_the_array);

V

Thanks Victor,

the question was not that clear to me whether I could use function
overloading or not, but that seems as the only opportunity...
I also thought using some kind of size argument with overloaded
functions but your solution is better.

Best,
Umut
 
P

Paul Bibbings

utab said:
How can I make a template function to work both with an array and a
vector such as:
template<class T>
T median(vector<T> v)
{
typedef typename std::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];
}

I would probably change your 'median' to accept a pair of
const_iterators (start and end). Then you can initialize a local vector
with them and do exactly like you do with your 'v' argument. When you
call it for a vector, you do

median(myvector.begin(), myvector.end())

and for an array you do

median(array, array + size_of_the_array);

V

Thanks Victor,

the question was not that clear to me whether I could use function
overloading or not, but that seems as the only opportunity...
I also thought using some kind of size argument with overloaded
functions but your solution is better.

I would agree that something along the lines of Victor's solution is the
better way to go. The following is just to give an example of how you
/could/ go down the function overloading route:

#include <vector>
#include <algorithm>
#include <stdexcept>
#include <iostream>

template<class T>
T median(std::vector<T> v)
{
typedef typename std::vector<T>::size_type vec_sz;
vec_sz size = v.size();
if (size == 0)
throw std::domain_error("median of an empty vector");
std::sort(v.begin(), v.end());
vec_sz mid = size/2;
return size % 2 == 0 ? (v[mid] + v[mid - 1])/2 : v[mid];
}

template<class T, unsigned N>
T median(const T(&a)[N])
{
T tmp_arr[N];
for (unsigned i = 0; i < N; ++i)
tmp_arr = a;
std::sort(tmp_arr, tmp_arr + N);
unsigned mid = N/2;
return N % 2 == 0 ? (tmp_arr[mid] + tmp_arr[mid - 1])/2
: tmp_arr[mid];
}

int main()
{
std::vector<double> d_vec;
const unsigned ARR_SIZE = 6;
double d_arr[ARR_SIZE] = { 7.9, 2.3, -1.1, 4.7, 9., 4.3 };
for (unsigned i = 0; i < ARR_SIZE; ++i)
d_vec.push_back(d_arr);
std::cout << "median(d_vec): " << median(d_vec) << '\n';
std::cout << "median(d_arr): " << median(d_arr) << '\n';
}

/**
* Output:
* median(d_vec): 4.5
* median(d_arr): 4.5
*/

There are, perhaps, some design issues here, however. For example, the
median of a vector<int> or int[] may not necessarily be representable by
an int, as you are of course aware.

Regards

Paul Bibbings
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top