2016-08-27 3 views
1

正確に2つのタイプのオブジェクトをベクトルに格納する必要があります。どちらのタイプもほとんど共通していません。デザインパターン、2つの可能なタイプのそれぞれのオブジェクトのベクトル

ベクターに格納した後、タイプに応じてそのベクターを繰り返し処理してアクションを実行します。

私の考え、これまで:

  • ポリモーフィズム。オーバーキル、と私はおそらくこれを行うだろうと、ずっと私を助けていないでしょう。

    if(dynamic_cast<T1>() != nullptr) { 
        ... 
    } else { 
        ... 
    } 
    
  • は、両方のタイプ(メソッドやフィールド)をマージし、ブール値を追加し、そのタイプ1または2

場合表します

どちらのパターンも私にとっては全く不器用なようですが、単純には完全に単純な解決策がありますが、私は単に見ません。

struct PatternMatch { 
    int length; 
    int indexInDict; 
} 

二 1:

第1のタイプは、このようなものである

struct NoMatch { 
    std::string rawChars; 
} 
+0

2つのメンバー変数を持つ 'class'を作成しないのはなぜですか? 1つは 'PatternMatch'で、2つ目は' NoMatch'です。次に、そのクラスのオブジェクトを保持するベクトルを作成しますか? – KostasRim

+2

継承と仮想関数を使用する場合は、 'dynamic_cast'を行う必要はありません。実際には、これが多形性のすべてです(dynamic_castは正反対のアプローチです)。 –

+2

なぜ2つのベクトルがないのですか? –

答えて

1

あなたは2種類のみを持っており、この数はCっぽいタグ付けされた労働組合が十分で使いやすい、将来的に成長しないことがわかっている場合:

struct PatternMatch { 
    int length; 
    int indexInDict; 
}; 

struct NoMatch { 
    std::string rawChars; 
}; 

struct TaggedUnion { 
    enum { MATCH, NO_MATCH } flag; 
    union { 
    PatternMatch match; 
    NoMatch noMatch; 
    }; 
}; 

、あなたが作成することができますTaggedUnionsのベクトルとflagデータメンバーを調べて、各要素の実際の型を調べます。

+0

私は避けた(これは魔法を少し恐れていた)...しかし、これは私の問題の解決策であるようです。 – J0hnD0e

+0

@ J0hnD0e組合の裏には魔法はありません。 :-) – skypjack

5

使用boost::variantまたはその他の "スタックベースのユニオンコンテナを区別しました"。私はまたvisiting the variant using lambdasを提案する。

// Either `A` or `B`. 
using my_type = boost::variant<A, B>; 

std::vector<my_type> my_vec; 

// ...`emplace_back` stuff into `my_vec`... 

auto visitor = make_lambda_visitor<void>(
    [](A&) { /* do something with A */ }, 
    [](B&) { /* do something with B */ } 
); 

for(auto& x : my_vec) 
{ 
    boost::apply_visitor(visitor, x); 
} 

C++ 17がstd::variantを持っていることに注意してください。

+0

私はまた、訪問者のパターンについては、私は(trivially)と解決することができます唯一の問題は、:私は2つの連続NoMatchesを1つにコレクションを反復しながらマージしたいが、私は質問でそれを言っていない – J0hnD0e

関連する問題