2013-04-05 73 views
4

我所擁有的是一樣的東西:使用std :: initializer_list創建樹?

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類(以及可能的輔助類) - 但它應該是tree-ish-like運算符,作爲TreeNode內容和容納子節點的容器(例如std :: vector)。

在C++中可以使用這樣的initializer_list來初始化樹狀結構嗎? (如果可能的話,一個提示如何做到這一點就好了。)

回答

5

下可能會爲你工作:

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

這是live example


更新:正如在另一個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 << ")"; 
    } 
} 

這裏的更新的live example

+0

感謝您的回答。這非常有幫助。 – 2013-04-06 08:43:36