以通用方式对所有结构成员求和

Sum all struct members in a generic way

我有很多代表计数器的 C 结构。 这些结构由多个相同类型的成员组成,比方说 uint64_t。在程序中,我有多个相同结构的实例,在某些情况下,我需要对所有这些相同结构求和。我不想为此使用 operator+,因为将来结构可能会更改并且有更多或更少的成员,我也不想总是修改运算符。

我认为我可以使用 sizeof 并从该结构创建结构成员类型的数组,然后对数组求和。我会把那个结构和一个数组结合起来。这将解决我不想在添加或删除新成员时修改运算符的问题,但这仅在结构仅包含相同类型的成员时才有效。

所以也许有一些通用的模板方法可以做到这一点,但我对模板不是很好,所以我向 C++ 专家寻求帮助。

这种结构的例子:

struct counter{
    uint64_t a;
    uint64_t b;
    uint64_t c;
    uint64_t d;
    uint64_t e;
};

这不是最好的方法,但实现您需要的功能的一种方法是:

/* counter.xh */
COUNTER_MEMBER(uint64_t, a);
COUNTER_MEMBER(uint64_t, b);
COUNTER_MEMBER(uint64_t, c);
COUNTER_MEMBER(uint64_t, d);
COUNTER_MEMBER(uint64_t, e);

然后在一些header:

/* counter.h */

struct counter{
#define COUNTER_MEMBER(TYPE,NAME) TYPE NAME;
    #include "counter.xh"
};

现在添加功能:

/* foo.cpp */
uint64_t add_members(const counter &obj) {
  uint64_t sum = 0LLU;
#define COUNTER_MEMBER(TYPE,NAME) sum += obj.NAME;
#include "counter.xh"
  return sum;  /* I hope there was no overflow */
}

Live example

我认为这不是最好的解决方案,但它可能是一个有用的方法。 如果 struct Counter 有更多或更少的成员,我只更改 GetSumOfAll() 功能。

struct Counter 
{
    uint64_t a;
    uint64_t b;
    uint64_t c;
    uint64_t d;
    uint64_t e;
};
typedef std::vector< Counter > VecCounter;

uint64_t GetSumOfMember( const VecCounter& vec, uint64_t Counter::*member )
{
    uint64_t sum = 0;

    std::for_each( vec.begin(), vec.end(), [&]( const Counter& counter )
    {
        sum += counter.*member;
    });

    return sum;
}

uint64_t GetSumOfAll( const VecCounter& vec )
{
    uint64_t sumA = GetSumOfMember( vec, &Counter::a );
    uint64_t sumB = GetSumOfMember( vec, &Counter::b );
    uint64_t sumC = GetSumOfMember( vec, &Counter::c );
    uint64_t sumD = GetSumOfMember( vec, &Counter::d );
    uint64_t sumE = GetSumOfMember( vec, &Counter::e );

    return sumA + sumB + sumC + sumD + sumE;
}

int main()
{
    VecCounter v{ { 1, 2, 3, 4, 5 }, { 2, 3, 4, 5, 6 } };
    uint64_t sum = GetSumOfAll( v );

    return 0;
}