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

(在实践中你可能想结合iand c

这是一个活生生的例子


更新:正如我在另一个 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 回答