2

これは私の最初の質問なので、うまくいけば良い質問です (回答を検索しましたが、まだ見つかりません)。

C++ で記述されたイベント ベースの疾患モデルがあり、それを OOP に変換しようとしています (部分的には私自身の学習経験のため)。基本クラス (群れ) には、感受性、感染性、および耐性のある動物の数と、発生する可能性のあるイベントの割合が格納されます。

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.
};  

次に、vector追跡する群れがあります。このモデル全体を通して、イベントによって群れ内の個人の数またはカテゴリが変更された後、すべての群れの各メンバーの合計を計算する必要があります (これは頻繁に発生します)。すでに 4 つのカテゴリと 5 つのイベントがあり、このモデルは簡単に拡張でき、さらに多くのイベントが必要になります。

私の古い手続き型コードでは、メンバーごとに個別のベクトルがありsum()、結果を計算する関数を作成するのは簡単でしたが、別の sum 関数を書かないとクラスでこれを行う方法がわかりません各メンバー(これは可能ですが、それが特に良い方法であるとは思えません)。合計を追跡する静的メンバー (例: sum_S) を作成し、イベントが発生するたびに更新することもできますが、これはすべてのメンバーに適しているとは限りません。料金に関しては。

sum()必要なメンバーをパラメーターとして取り、すべての群れでその特定のメンバーの合計を返す単一の関数を作成する方法はありますか?

ありがとうございました!

4

3 に答える 3

4

標準ライブラリのヘッダーnumericには、関数 calculate が含まれています。それはあなたが望むことを正確に行うわけではありませんが、簡単に適応できます:

#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;
}

このコードではinitializer_listsラムダとラムダを使用しています。これらがコンパイラでサポートされていない場合は、対応する C++03 コード (push_backおよびファンクタ) を使用します。

于 2013-05-15T09:35:05.623 に答える
0

Stateだから、これは私が最終的に得たものです(を含むシミュレーション状態を保持すると呼ばれるクラス内vector<Herd>):

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;
    ...
}

これは、個体数 ( ints) とイベント レート ( floats) の両方に対して機能し、メンバー関数へのポインターを使用してこれらの値を保持しますprivate。これがコードでどのように呼び出されるかの例は次のとおりです。

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)

特に Potatoswatter には大変お世話になりました。これは、以前の退屈なボイラープレート コードよりもはるかに優れています。

于 2013-05-27T14:54:34.690 に答える