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

时间:2016-05-30 07:14:47

标签: c++ gcc c++98

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

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

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

此类结构的示例:

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

2 个答案:

答案 0 :(得分:2)

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

/* 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);

然后在一些标题中:

/* 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

答案 1 :(得分:0)

我认为这不是最佳解决方案,但它可能是一种有用的方法。 如果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;
}