Использование параметра типа и указателя на один и тот же параметр типа в шаблоне функции - PullRequest
1 голос
/ 26 апреля 2010

Я написал шаблонную функцию для определения медианы любого вектора или массива любого типа, который можно отсортировать с помощью sort . Функция и небольшая тестовая программа приведены ниже:

#include <algorithm>
#include <vector>
#include <iostream>
using namespace::std;

template <class T, class X>
void median(T vec, size_t size, X& ret)
{
    sort(vec, vec + size);
    size_t mid = size/2;
    ret =  size % 2 == 0 ? (vec[mid] + vec[mid-1]) / 2 : vec[mid];
}

int main()
{
    vector<double> v;
    v.push_back(2); v.push_back(8);
    v.push_back(7); v.push_back(4);
    v.push_back(9);

    double a[5] = {2, 8, 7, 4, 9};

    double r;
    median(v.begin(), v.size(), r);
    cout << r << endl;
    median(a, 5, r);
    cout << r << endl;
    return 0;
}

Как видите, функция median принимает в качестве аргумента указатель, T vec . Также в списке аргументов есть ссылочная переменная X ret , которая модифицируется функцией для хранения вычисленного медианного значения.

Однако я не считаю это очень элегантным решением. T vec всегда будет указателем того же типа, что и X ret . Мои первые попытки написать median имели такой заголовок:

 template<class T>
 T median(T *vec, size_t size)
 {
      sort(vec, vec + size);
      size_t mid = size/2;
      return size % 2 == 0 ? (vec[mid] + vec[mid-1]) / 2 : vec[mid];
 }

Я тоже пробовал:

 template<class T, class X>
 X median(T vec, size_t size)
 {
      sort(vec, vec + size);
      size_t mid = size/2;
      return size % 2 == 0 ? (vec[mid] + vec[mid-1]) / 2 : vec[mid];
 }

Я не мог заставить ни одного из них работать. Мой вопрос: может ли кто-нибудь показать мне работающую реализацию любой из моих альтернатив?

Спасибо за внимание!

Ответы [ 2 ]

3 голосов
/ 26 апреля 2010

Идиоматический подход заключается в использовании итераторов. Чтобы включить это, вы можете получить тип возвращаемого значения из итератора:

template <class I>
typename iterator_traits<I>::value_type median(I start, I finish)
{
    ...
}
0 голосов
/ 21 февраля 2012

Я бы сделал это:

template <class T>
void median( T* vec, size_t size, T& ret )
{
    sort( vec, vec + size );
    size_t mid = size/2;
    ret =  size % 2 == 0 ? ( vec[mid] + vec[mid-1] ) / 2 : vec[mid];
}

template <class T>
void median( vector<T>& vec, T& ret )
{
        median( &*vec.begin(), vec.size(), ret );
}

Но это только я.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...