Реорганизация «тупой» функции в общий стиль STL с итераторами в контейнеры - PullRequest
4 голосов
/ 07 июня 2010

Мне удалось обернуть голову вокруг некоторых функциональных возможностей C ++ (for_each, функции отображения, использование итераторов ...), но создание шаблонов и списков аргументов функций для приема в обобщенных контейнерах и итераторах все еще не позволяет мне.У меня есть практический пример, который, я надеюсь, кто-то может проиллюстрировать для меня:

Возьмите следующую функцию, которая обрабатывает входящий std :: vector и создает промежуточный итог из множества точек данных / итераций процесса:

/* the for-loop method - not very savvy */
void UpdateRunningTotal (int_vec& total, int_vec& data_point) {
  for (int i = 0; i < V_SIZE; i++) {
    total[i] += data_point[i];
  }
}

typedef int_vec std::vector<int>;
int_vec running_total (V_SIZE, 0);  // create a container to hold all the "data points" over many iterations
/* further initialization, and some elaborate loop to create data points */

UpdateRunningTotal (running_total, iteration_data);
/* further processing */

Вышеописанное работает, но я бы предпочел иметь функцию, которая принимает итераторы и выполняет это суммирование.Еще лучше иметь общий список параметров с выводимым типом вместо указания типа контейнера, например:

UpdateRunningTotal (iteration_data.begin(), iteration_data.end(), running_total.begin());

Я действительно потерян в этот момент и мне нужно небольшое руководство, чтобы найти, как определить шаблони списки аргументов, чтобы сделать функцию общей.Как будет выглядеть шаблон и определение функции?Я уже знаком с способом выполнения этой конкретной задачи с использованием функциональности STL - я ищу иллюстрацию определения общей функции / шаблона.

Ответы [ 2 ]

7 голосов
/ 07 июня 2010

Вы можете использовать std::transform и std::plus:

std::transform(iteration_data.begin(), iteration_data.end(),
                running_total.begin(), iteration_data.begin(), std::plus<int>());

И в вашей функции это будет:

template <typename Iter1, typename Iter2>
void UpdateRunningTotal(Iter1 pBegin, Iter1 pEnd, Iter2 pBegin2)
{
    typedef typename std::iterator_traits<Iter1>::value_type value_type;

    std::transform(pBegin, pEnd, pBegin2, pBegin, std::plus<value_type>());
}
1 голос
/ 07 июня 2010

Хорошо, я мог бы дать вам сигнатуру функции, которую вы должны будете заполнить правильной реализацией, поскольку ваша спецификация сейчас не имеет смысла для меня.


template < typename InputIterator, typename OutputIterator >
?? UpdateRunningTotal(InputIterator beg, InputIterator end, OutputIterator dest)
{
}
...