5

私が持っているのは次のようなものです:

struct ExprTreeNode {
   char c;
   std::vector< int > i;
};

ExprTreeNode tn { '+', { 1, 2, 3, 4 } };

書きたいことは次のようなものです。

MyTree t1 { '+', { 1, 2, { '*', { 3, 4, 5 } } } };
MyTree t2 { '*', { { '+', { 77, 88, 99, 111 } }, { '-', { 44, 33 } } } };

MyTree クラス (および可能性のあるヘルパー クラス) を自由に定義できますが、それは、TreeNode コンテンツおよびサブノードを保持するコンテナー (std::vector など) としての演算子のような、ツリーのようなものである必要があります。

C++ では、そのような initializer_list を使用してツリーのような構造を初期化することは可能ですか? (可能であれば、これを行う方法のヒントがいいでしょう。)

4

1 に答える 1

6

以下はあなたのために働くかもしれません:

struct ExprTreeNode {
    bool is_value;
    int i;
    char c;
    std::vector< ExprTreeNode > v;

    ExprTreeNode( int i_ ) : is_value( true ), i( i_ ) {}
    ExprTreeNode( char c_, std::initializer_list< ExprTreeNode > v_ )
      : is_value( false ), c( c_ ), v( v_ ) {}
};

ExprTreeNode tn { '+', { 1, 2, { '*', { 3, 4 } } } };

(実際には、 と を組み合わせたいと思うかもしれませic)

これが実際のです。


更新:同様の手法を使用した別の Q/A で指摘されたように、上記はstd::vector<ExprTreeNode>メンバーとして使用しているため未定義の動作であり、その時点でExprTreeNodeは完全な型ではありません。以下で修正する必要があります。

struct ExprTreeNode {
    int value_;
    char op_;
    std::shared_ptr< void > subnodes_;

    ExprTreeNode( int v ) : value_( v ) {}
    ExprTreeNode( char op, std::initializer_list< ExprTreeNode > subnodes );

    void print() const;
};

typedef std::vector< ExprTreeNode > Nodes;

ExprTreeNode::ExprTreeNode( char op, std::initializer_list< ExprTreeNode > l )
  : op_(op), subnodes_(std::make_shared<Nodes>(l))
{}

これは、shared_ptrリーフ/非リーフのフラグとしても使用します。使用する場合は、最初にキャストする必要があります。

void ExprTreeNode::print() const
{
   if( !subnodes_ ) {
      std::cout << value_;
   }
   else {
      std::cout << op_ << " ( ";
      for( const auto& e : *std::static_pointer_cast<Nodes>(subnodes_) ) {
         e.print(); std::cout << " ";
      }
      std::cout << ")";
   }
}

更新されたライブの例は次のとおりです。

于 2013-04-05T22:07:35.887 に答える