2017-10-26 25 views
0

私のパーサは、空のNode基本構造体から継承するNodeSomething構造体で構成される抽象構文木を作成しています。これらはstd::list<Node>に格納されています。空の基底クラスから継承する構造体の初期化リストを使用する

私の問題は、すべての単一NodeSomethingのコンストラクタを記述したくないということです。構造体はすべて基底クラスから継承しているため、集約されていません。したがって、私は初期化リスト(brace initalisation) )。

これらの構造体はすべて、非常に単純で、大部分は1つまたは2つのintまたはstring変数を含んでいるため、それらすべての基本コンストラクタを記述する必要があります。私は継承の必要性を取り除きますが、これらのNodeサブクラスの汎用リストを作成するためのより良い方法はありません。

は、とにかくここにいくつかは、私が何を意味するかを説明するために、コードサンプルをトリミングしています:

struct Node {}; 

struct NodePerson : Node 
{ 
    std::string name; 
    int age; 
}; 

struct NodeVariable : Node 
{ 
    int val; 
}; 

そして、このような実装何かに:

std::list<Node> tree; 

tree.push_back(NodePerson {"Paul", 23}); 

これはno matching constructor for initalization of 'NodePerson'エラーを吐き出す、その後、3う暗黙的な移動、コピー、およびデフォルトのコンストラクタに対する引数の不一致(2は期待通り1)

structsはもはや集約ではなく、ブレース不活性化を使用できないので、これは予想される動作ですが、それぞれのコンストラクタを記述することは非常に不公平です。これには簡単な解決策がありますか?

編集:わからなかったので、Nodeは継承のためだけに使用される抽象クラスであるため、異なるノードタイプのリストを保存することができます。

+0

'NodePerson'クラスを削除しますか?とにかく 'Node'オブジェクトを格納しているので、必要はありません。 – juanchopanza

+0

クラス階層が本当にこのように見える場合、 'Node'へのポインタは基本的に役に立たない:それはメソッドを持たないので、何もすることはできません。あなたはデザインを考え直したいかもしれません。 – Brian

+0

私は 'Node'の実際のインスタンスを決して保管しません。それぞれの' NodeSomething'構造体は、ある種の仮想マシンによって実行されるキーワード/命令に対応するので、構造体型自体は有益な情報を運びます。命令。 – tokamach

答えて

0

集約初期化を使用しようとしています。これは、オブジェクトの各データメンバの初期化子のブレースリストを提供し、オブジェクトが持つ可能性のあるコンストラクタをバイパスします。

しかし、基本クラスの存在は、オブジェクトが集合体であることを不適格とします(C++ 14以前)。したがって、集約初期化を適用することはできません。

C++ 17では、「集約」の定義が拡張され、コードが合法になります。まだC++ 17コンパイラを使用できない場合は、コンストラクタを追加するなどの他のオプションに戻らなければなりません。

関連する問題