简体   繁体   English

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

[英]Sum all struct members in a generic way

I have a lot of of C struct which represent counters. 我有很多代表计数器的C结构。 Those structs consist of several members of the same type, let's say uint64_t . 这些结构由几个相同类型的成员组成,比方说uint64_t In the program I have several instances of the same struct and in some cases I need to sum all those same struct. 在程序中,我有几个相同结构的实例,在某些情况下,我需要对所有这些相同的结构求和。 I don't want to use operator+ for this because in future the structs can change and have more or less members and I don't want to always modify the operator as well. 我不想为此使用operator+ ,因为将来结构可以更改并且具有或多或少的成员,而且我也不想总是修改operator。

I thought that I could use a sizeof and create an array of struct's member type from the struct and then sum the array. 我以为可以使用sizeof并从该结构创建结构的成员类型数组,然后对该数组求和。 I would make an union of that struct and an array. 我会将该结构和数组合并。 This would solve my problem of not wanting to modify the operator when new member is added or removed, but this would work only while the struct contains only members of the same type. 这将解决我不想在添加或删除新成员时修改运算符的问题,但这仅在结构仅包含相同类型的成员时才有效。

So maybe there is some generic, template method of doing this, but I'm not that good with templates so I ask you C++ gurus for help. 因此,也许有一些通用的模板方法可以做到这一点,但是我对模板的了解并不好,所以我向您的C ++专家寻求帮助。

Example of such struct: 此类结构的示例:

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

Not the best way, but one way to achieve the functionality you need is: 不是最好的方法,但是实现所需功能的一种方法是:

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

Then in some header: 然后在一些标题中:

/* counter.h */

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

Now comes the add function: 现在来添加功能:

/* 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 现场例子

I think this is not the best solution, however it can be a useful method. 我认为这不是最佳解决方案,但是它可能是一种有用的方法。 If struct Counter have more or less members, I change GetSumOfAll() function only. 如果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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM