Есть много способов, в зависимости от того, что вы хотите сделать, насколько универсальным и многократно используемым должно быть решение, с какими ограничениями памяти у вас все в порядке (т. Е. Постоянно распределяемая память против некоторых связанных списков и т. Д.).Но вот простой пример с использованием C ++ 03:
#include <vector>
#include <list>
#include <iostream>
template <typename Iter, typename Selector>
inline double
average (Iter it, Iter end, Selector selector)
{
double average = 0.0;
size_t size = 0;
while (it != end)
{
average += selector (*it);
++size;
++it;
}
return size != 0 ? average / size : 0.0;
}
struct DoublingSelector
{
template <typename T>
inline T operator () (const T & item)
{
return item * 2;
}
};
int main ()
{
std::vector<int> data;
data.push_back (1);
data.push_back (3);
data.push_back (5);
std::cout << "The average is: " <<
average (data.begin (), data.end (),
DoublingSelector ()) << std::endl;
}
Возможно, будет гораздо проще предположить, например, что вы можете принимать только контейнеры высокого уровня (не массивы).И вы можете получить лямбды, добавив C ++ 0x, например:
#include <vector>
#include <iterator>
#include <iostream>
template <typename C, typename Selector>
inline double
average (const C & items, Selector selector)
{
auto it = std::begin(items);
auto end = std::end(items);
// Average is only meaningful on a non-empty set of items
assert(it != end);
double sum = 0.0;
size_t size = 0;
for (; it != end; ++it)
{
sum += selector(*it);
++size;
}
return sum / size;
}
int main ()
{
std::vector<int> data = { 1, 3, 5 };
std::cout << "The average is: " <<
average (data, [] (int v) { return v * 2; }) << std::endl;
}
Выбор за вами: -)
PS: Да, и это std::function
(чтона самом деле материал из Boost в pre-C ++ 0x) может быть использован для того, чтобы сделать ваш алгоритм не шаблонным.В противном случае он ограничивает вас только в отношении того, какой «селектор» вы можете передать.