按特定成员遍历结构容器

Iterate through container of structs by specific member

我有一个功能

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;

是否有一种优雅的方法来计算 v 中所有 a 结构成员的平均值?将 vector<T>::iterator 包装到提取 a 成员的迭代器的某种方法?

您需要告诉 mean() 要查看 T 的哪个成员。您可以为此使用 pointer-to-data-member,例如:

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(), &T::a/*or b*/);

Online Demo

您可以通过摆脱手动循环并使用 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,
        [&](double acc, const T &t){ ++n; return acc + t.*member; }
    );
    return s / n;
}

Online Demo

在这种情况下,您可以完全摆脱 mean()

#include <numeric>

vector<T> v;
// fill v...
double m = accumulate(v.begin(), v.end(), 0.0,
    [](double acc, const T &t){ return acc + t.a/*or b*/; }
) / v.size();

Online demo