2011-07-21 4 views
0

私はたくさんのデータを持っていて、ループの中で選択をする必要があります。すべてのエントリーは物理イベントです。enumよりも良い

for (...) { // loop over entries in the data 
    if (not selection()) continue; 
    ... 
} 

私は、粒子の特定のタイプを選択し、コマンドラインから考慮されるべき、例えば:

Options options = get_options(argc, argv); 

enum ParticleType_type {ELE, PHO, ...} 

cout << "particle: " << get_particle_name(options.particle_type); 

for (entry in data) { // loop over data 
    // read variale like PDG, conv, ... for the entry 
    switch (options.particle_type) 
    { 
      case ELE: if (PDG != 11) continue; break; 
      case PHO: if (PDG != 22) continue; break; 
      case PHO_UNC: if (PDG != 22 or conv) continue; break; 
      case PHO_CONV: if (PDG != 22 or !conv) continue; break; 
      case PHO_1TRK: if (PDG != 22 or !conv or !is1trak) continue; break; 
      case PHO_2TRK: if (PDG != 22 or !conv or !is2trak) continue; break; 
      case PHOR1:  if (PDG != 22 or !conv or !(r>0 and <=200) continue; break; 
      case PHOR2:  if (PDG != 22 or !conv or !(r>200 and <=400) continue; break; 
      case PHOR3:  if (PDG != 22 or !conv or !(r>400 and <=600) continue; break; 
      case PHOR4:  if (PDG != 22 or !conv or !(r>600 and <=800) continue; break; 
    } 

    do_something(); 

    if (isPhoton(options.particle_type)) // true for every PHO_XXX 
    { 
     if (options.particle_type in [PHORX]) 
     { 
       int rbin = get_Rbin(options.particle_type) // PHOR1 -> 1, PHOR2 -> 2 
       ... 
     } 
     ... 
    } 
} 

cout << "output: " << get_file_name(options.particle_type) + ".out"; 

あなたが見ることができるように:すべてのイベントでは、そのプロパティを持つ1つの粒子のみが存在し

  1. 例えばPHO_CONVPHOおよびで、サブカテゴリがある混乱
  2. をis'tはPHO_CONV
  3. すべてのParticleType_typeは名前、file_nameのと同様に、いくつかのプロパティを持っているより
  4. 今私は、いくつかの中に範囲をパラメータ化したいr 100のステップではなく200を使用してPHORxなどのカテゴリを倍増する必要がありますテンプレートの引数をおそらくどこかで使用しています
  5. カテゴリを作成する必要があります。PHOR1_1TRK
  6. (関連性は低いです)私はI/Oによって支配しています。現在、私は二回実行する必要がPHOELEを処理したい場合は、私はそれらをしたいと同時に、

私は最善の解決策は、すべてのParticleType_typeのための1つのクラスを作成し、としてget_file_nameのような機能を置くことだと思いますメンバー関数問題はクラスがオブジェクトではないため、関数の引数として渡すことができないことです。たとえば、enumを使用すると、ParType_typeを引数とするフリー関数を書くことができますが、クラスではできません。

PHORXなど、自動的にパラメトリックタイプを作成したいと考えています。

誰かがいくつかのテクニックを提案できますか?

+0

クラス型を引数として持つ関数を作成することはできません。それは基本的な質問ですか?もしそうなら、そうすることができます。 – Chad

+0

@チャド:どうですか? 'PartType_type'の決定は実行時に行われるので、テンプレートを使用することはできません。 –

+0

各タイプに対して特定の上書きを作成します。下記のMRABの答えをご覧ください。 – Chad

答えて

1

パーティクルタイプごとにクラス(サブクラスの抽象クラス(可能であれば抽象クラス)を作成する)は、正しいアプローチのように見えます。

クラスを関数に渡すことはありません。そのクラスのインスタンスを渡すことになります。

0

すべてのパーティクルに別々のクラスを書くのではなく、テーブル駆動型のメソッドを使用できます(たとえばhere参照)。

ParticleType_typeをインデックスとして使用して関数ポインタを取得するテーブル、またはboost::functionを使用してパーティクル固有の処理を行うテーブルを作成します。

3

ここではFlyweight patternが役に立ちます。

型の列挙型を持つ各パーティクルのインスタンスを持つ代わりに、各パーティクル型の単一のインスタンスと、その型の各パーティクルのこのインスタンスへのポインタを持ちます。パーティクルタイプは、計算のためにパーティクル構造体へのポインタをとります。

// pseudocode! 
ParticleA a; 
ParticleB b; 

struct ParticleData { 
    Particle * type; 
    int data; 
} particles[] = { 
    { &a, 5 }, 
    { &a, 7 }, 
    { &b, 4 }, 
// ... 
}; 

for each(particle in particles) { 
    particle->type->do_something(particle); 
} 
関連する問題