Using std :: initializer_list to create a tree?

I have something like:

struct ExprTreeNode { char c; std::vector< int > i; }; ExprTreeNode tn { '+', { 1, 2, 3, 4 } }; 

I want to write something like:

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

I can define the MyTree class (and possible helper classes), but it should be something like a tree-ish type, like the contents of a TreeNode and a container (like std :: vector) containing trays.

In C ++, is it possible to use such an initializer_list to initialize a tree structure? (If possible, a hint on how to do this would be nice.)

+4
source share
1 answer

For you, the following may be done:

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

(in practice you can combine i and c )

Here is a living example .


Update: As pointed out in another Q / A, where I used a similar method, the above behavior is undefined, since I use std::vector<ExprTreeNode> as a member, and at this point, ExprTreeNode not a full type. The following needs to be fixed:

 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)) {} 

Here shared_ptr used as well as a flag for a sheet / non-sheeted sheet, and if you want to use it, you need to transfer it first:

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

Here's an updated live example .

+5
source

All Articles