#c #c 17
Вопрос:
У меня есть функция
template<typename I> double mean(I begin, I end)
{
double s = 0;
size_t n = 0;
while(begin != end)
{
s = *begin ;
n;
}
return s / n;
}
и вектор структур T:
struct T
{
double a;
double b;
};
vector<T> v;
Есть ли элегантный способ вычислить среднее значение всех a
членов структур в v
? Какой-то способ обернуть vector<T>::iterator
в итератор, который извлекает a
элемент?
Комментарии:
1.
boost::transform_iterator
иstd::ranges::views::transform
с диапазоном C 20.2. Просто к вашему сведению, ваша
mean()
функция технически возвращает среднее значение, поэтому я бы назвал ееaverage()
вместо этого.3. Действительно. Спасибо!
Ответ №1:
Вам нужно будет сказать mean()
, на какого члена T
смотреть. Для этого вы можете использовать указатель на элемент данных, например:
template<typename Iter, typename T>
double mean(Iter begin, Iter end, double (T::*member))
{
double s = 0;
size_t n = 0;
while (begin != end)
{
s = (*begin ).*member;
n;
}
return s / n;
}
struct T
{
double a;
double b;
};
vector<T> v;
// fill v...
double m = mean(v.begin(), v.end(), amp;T::a/*or b*/);
Вы могли бы пойти дальше, избавившись от ручного цикла и используя std::accumulate()
вместо этого, например:
#include <numeric>
template<typename Iter, typename T>
double mean(Iter begin, Iter end, double (T::*member))
{
size_t n = 0;
double s = std::accumulate(begin, end, 0.0,
[amp;](double acc, const T amp;t){ n; return acc t.*member; }
);
return s / n;
}
В этом случае вы могли бы просто полностью избавиться от mean()
:
#include <numeric>
vector<T> v;
// fill v...
double m = accumulate(v.begin(), v.end(), 0.0,
[](double acc, const T amp;t){ return acc t.a/*or b*/; }
) / v.size();
Комментарии:
1. Выглядит великолепно. Большое спасибо!