Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 对象数组中特定成员的总和_C++_Sum_Member - Fatal编程技术网

C++ 对象数组中特定成员的总和

C++ 对象数组中特定成员的总和,c++,sum,member,C++,Sum,Member,这是我在这里的第一个问题,希望这是一个好问题(我已经找到了答案,但还没有找到) 我有一个基于事件的疾病模型,用C++编写,我试着把它转换成面向对象编程(部分是为了我自己的学习经验)。基本类(畜群)存储易感、感染和抗性动物的数量以及可能事件发生的速率 class Herd { private: int S,I,R,N; float birth, death, infection, recovery, movement; public:

这是我在这里的第一个问题,希望这是一个好问题(我已经找到了答案,但还没有找到)

我有一个基于事件的疾病模型,用C++编写,我试着把它转换成面向对象编程(部分是为了我自己的学习经验)。基本类(畜群)存储易感、感染和抗性动物的数量以及可能事件发生的速率

class Herd {  
    private: 
        int S,I,R,N;  
        float birth, death, infection, recovery, movement;  
    public:  
        void calc_birth(void) { birth = r*N*(1.0-N/c); }  
        void calc_infection(void) { infection = N>0 ? beta*S*I/N : 0.0; }  
        // etc.
};  
然后我有一个畜群的
向量
来跟踪。在整个模型中,我需要计算所有群体中每个成员的总和,在事件改变了群体中个体的数量或类别之后(这种情况经常发生)。我已经有4个类别和5个事件,这个模型可以很容易地扩展,需要更多

在我以前的过程代码中,我只是为每个成员创建了一个单独的向量,很容易创建一个
sum()
函数来计算结果,但是如果不为每个成员编写一个单独的sum函数,我看不出如何在类中实现这一点(这是可能的,但我怀疑这是一种特别好的方法)。我可以创建一个静态成员(例如,
sum_S
)来跟踪总数,并在每次事件发生时更新它,但这可能不适合所有成员,而且我不确定当涉及到费率时,总数是否会慢慢偏离真实值

有没有一种方法可以编写一个
sum()
函数,将我想要的成员作为参数,并返回所有群中该特定成员的总和


谢谢大家!

当然可以,使用指向成员的指针

float sum_for_member( std::vector< Herd > const &herds, float Herd::*member ) {
    float acc = 0;
    for ( std:vector< Herd >::const_iterator it = herds.begin();
                                             it != herds.end(); ++ it ) {
        acc += (*it).*member;
    }
    return acc;
}
如果要改用成员函数
getRecovery
,则参数声明变为
float(Herd::*member)(
,求和变为
acc+=((*it)。*member)(


如果你不害怕从OO和一般的C++风格中走得更远,你可以使用函数模板,让标准库负责循环:

template< float Herd::*member >
float plus( float lhs, Herd const &rhs )
    { return lhs + rhs.*member; }

vector< Herd > h;
std::accumulate( h.begin(), h.end(), 0., plus< & Herd::recovery > );
template
浮动附加(浮动左侧、羊群常数和右侧)
{返回lhs+rhs.*成员;}
向量h;
标准::累积(h.开始(),h.结束(),0.,加上<&Herd::recovery>);

标准库标题
numeric
包含该函数。它不能完全满足您的需求,但很容易适应:

#include <numeric>
#include <vector>
#include <iostream>

struct Foo {
  int member;
};


int main()
{
  std::vector<Foo> v = { {1}, {2}, {3} };

  int sum 
    = std::accumulate(begin(v), end(v), 0,
                      // lambda that sums up
                      [](const int& x, const Foo& y)
                      {return x + y.member;});
  std::cout << sum << std::endl;

  return 0;
}
#包括
#包括
#包括
结构Foo{
国际会员;
};
int main()
{
向量v={{1},{2},{3};
整数和
=标准::累计(开始(v),结束(v),0,
//总而言之
[](常量内部和x,常量Foo和y)
{返回x+y.member;});

std::cout这就是我最终得到的结果(在一个名为
State
的类中,该类保存模拟状态,包括一个
向量
):

等等


非常感谢你的帮助,尤其是Potatoswatter,这比我以前的繁琐的样板代码要好得多。

听起来你想要一个模式或配方,而不是一个C++ >代码>模板<代码>,所以我删除了标签。这就省去了我记住语法和回答的麻烦。
foo=sum\u for_member(herdVector,&Herd::S)//畜群中易感动物的总数
谢谢,我已经做到了。唯一的一件事是我需要将成员公开才能实现这一点。如果我想让成员保持私有,我是否应该研究某种包含函数的friend类(我不确定这是否真的是必要的)@spaceLem您可以向
Herd
添加四个静态单行函数,为适当的成员调用sum_for_成员。例如
static float sum_of_s(std::vectorconst&herdVector){return sum_for_成员(herdVector,&Herd::s)在C++中,与java不同,类不应该只包含函数。FoeLoad函数与成员类似,可以在类{} < /C>范围内定义(这进入头,隐式<代码>内联)。虽然,如果它们是私有的,外部客户端如何指定要求和的是哪一个?@Roddy可以这样做,尽管将来成员数量可能会增加,我试图避免像那样复制大量代码。我希望最多只能定义getX()对于每个成员,并将其用作求和中的某种参数。这确实有效,但成员在结构中默认为公共成员。对于私有成员有类似的想法吗(类似于调用y.get()而不是y.S)?这与他可能开始的样板循环几乎没有什么不同。@spaceLem当然,只需调用成员函数,而不是
y.member
@Potatoswatter我同意。将调用封装到接受范围和成员指针的对象中肯定会更好。嗯,看起来初始值也用于确定ty累加器的pe,因此指定
0
将导致它在每次添加后舍入。需要为
0。
#include <numeric>
#include <vector>
#include <iostream>

struct Foo {
  int member;
};


int main()
{
  std::vector<Foo> v = { {1}, {2}, {3} };

  int sum 
    = std::accumulate(begin(v), end(v), 0,
                      // lambda that sums up
                      [](const int& x, const Foo& y)
                      {return x + y.member;});
  std::cout << sum << std::endl;

  return 0;
}
Class State {
    ...
    template <typename T>
        T sum(T (Herd::*getter)()) {
        T acc = (T) 0.0;
        for (int i=0; i<size; ++i) {
            acc += (herds[i].*getter)();
            }
        return acc;
    ...
}
cout << "total # of S = " << state.sum(&Herd::getS)
    "total # of I = " << state.sum(&Herd::getI)
    "total birth rate = " << state.sum(&Herd::get_birth)
    "total infection rate = " << state.sum(&Herd::get_infection)