以下はあなたのために働くかもしれません:
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 } } } };
(実際には、 と を組み合わせたいと思うかもしれませi
ん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 << ")";
}
}
更新されたライブの例は次のとおりです。