我正在嘗試創建一棵樹。我的第一個要求是,樹級中的對象按其插入順序排序。如何使用boost多索引容器創建樹
作爲第一次嘗試我用STL的vector類:
#include <vector>
#include <iostream>
#include <string>
class Node;
typedef std::vector<Node> NodeList;
class Node
{
public:
Node(const std::string& name, int val=0): name_(name), value_(val), list_() {}
Node(const Node& nd): name_(nd.name_), value_(nd.value_), list_(nd.list_) {}
Node& operator=(const Node& nd)
{
name_ = nd.name_;
value_ = nd.value_;
list_ = nd.list_;
return *this;
}
const std::string& name(void) const {return name_;}
NodeList& list(void) {return list_;}
const NodeList& list(void) const {return list_;}
int value(void) const {return value_;}
void value(int val) {value_ = val;}
private:
std::string name_;
int value_;
NodeList list_;
};
std::ostream& operator<<(std::ostream& os, const Node& nd)
{
os << nd.name() << "=\"" << nd.value() << "\"";
return os;
}
std::ostream& operator<<(std::ostream& os, const NodeList& ndlst)
{
for(NodeList::const_iterator it = ndlst.begin(); it < ndlst.end(); it++)
{
os << ' ' << *it;
}
return os;
}
int main()
{
std::cout << "Creating a little tree..." << std::endl;
Node a("ROOT", 1);
a.list().push_back(Node("LEVEL1_1", 21));
a.list().push_back(Node("LEVEL1_2", 22));
a.list().push_back(Node("LEVEL1_3", 23));
a.list().push_back(Node("LEVEL1_4", 24));
a.list().at(2).list().push_back(Node("LEVEL2_1", 231));
std::cout << "Done. Now let's see some values." << std::endl;
std::cout << "root: " << a.value() << ", root->node2: "
<< a.list().at(1).value()
<< ", root->node3->node1: "
<< a.list().at(2).list().at(0).value()
<< std::endl;
std::cout << "Ok, now let's use our '<<' operators." << std::endl;
std::cout << a << std::endl;
std::cout << a.list() << std::endl;
return 0;
}
這個小程序編譯確定,按照預期執行。
作爲了一步,我想補充訪問其名稱樹級別對象的能力,所以我tryed使用boost多指標,所以我修改了Node類,如下所示:
class Node;
struct Name{};
typedef boost::multi_index::multi_index_container<
Node,
boost::multi_index::indexed_by<
boost::multi_index::random_access<>,
boost::multi_index::hashed_non_unique<
boost::multi_index::tag<Name>,
boost::multi_index::const_mem_fun<Node, const std::string&, &Node::name>
>
>
> NodeList;
class Node
{
public:
Node(const std::string& name, int val=0): name_(name), value_(val), list_() {}
Node(const Node& nd): name_(nd.name_), value_(nd.value_), list_(nd.list_) {}
Node& operator=(const Node& nd)
{
name_ = nd.name_;
value_ = nd.value_;
list_ = nd.list_;
return *this;
}
const std::string& name(void) const {return name_;}
int value(void) const {return value_;}
void value(int val) {value_ = val;}
NodeList& list(void) {return list_;}
const NodeList& list(void) const {return list_;}
private:
std::string name_;
int value_;
NodeList list_;
};
但它根本不能編譯。使用gnu g ++版本4.6.1第一個錯誤是
tree.cpp:19:65: error: incomplete type 'Node' used in nested name specifier
有人可以幫我解決這種相互依賴嗎?
非常感謝。
問候
感謝詹姆斯霍普金,我有計劃部分工作:
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/random_access_index.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/identity.hpp>
#include <boost/multi_index/global_fun.hpp>
#include <iostream>
#include <string>
class Node;
struct Name{};
const std::string& getNodeName(const Node& nd);
typedef boost::multi_index::multi_index_container<
Node,
boost::multi_index::indexed_by<
boost::multi_index::random_access<>,
boost::multi_index::hashed_non_unique<
boost::multi_index::tag<Name>,
boost::multi_index::global_fun<const Node&, const std::string&, &getNodeName>
>
>
> NodeList;
class Node
{
public:
Node(const std::string& name, int val=0): name_(name), value_(val), list_(new NodeList) {}
Node(const Node& nd): name_(nd.name_), value_(nd.value_), list_(new NodeList(*nd.list_)) {}
virtual ~Node() {delete list_;}
Node& operator=(const Node& nd)
{
name_ = nd.name_;
value_ = nd.value_;
*list_ = *nd.list_;
return *this;
}
const std::string& name(void) const {return name_;}
int value(void) const {return value_;}
void value(int val) {value_ = val;}
NodeList& list(void) {return *list_;}
const NodeList& list(void) const {return *list_;}
friend const std::string& getNodeName(const Node& nd);
private:
std::string name_;
int value_;
NodeList* list_;
};
const std::string& getNodeName(const Node& nd)
{
return nd.name_;
}
std::ostream& operator<<(std::ostream& os, const Node& nd)
{
os << nd.name() << "=\"" << nd.value() << "\"";
return os;
}
std::ostream& operator<<(std::ostream& os, const NodeList& ndlst)
{
for(NodeList::const_iterator it = ndlst.begin(); it < ndlst.end(); it++)
{
const Node& nd = *it;
os << ' ' << nd;
}
return os;
}
int main()
{
std::cout << "Creating a little tree..." << std::endl;
Node a("ROOT", 1);
a.list().push_back(Node("LEVEL1_1", 21));
a.list().push_back(Node("LEVEL1_2", 22));
a.list().push_back(Node("LEVEL1_3", 23));
a.list().push_back(Node("LEVEL1_4", 24));
// a.list().at(2).list().push_back(Node("LEVEL2_1", 231)); // First call to "at()" returns a read-only iterador so I can't append elements to its pointed object.
std::cout << "Done. Now let's see some values." << std::endl;
std::cout << "root: " << a.value() << ", root->node2: "
<< a.list().at(1).value() << std::endl;
/* << ", root->node3->node1: " << a.list().at(2).list().at(0).value()
<< std::endl; */
std::cout << "Ok, now let's use our '<<' operators." << std::endl;
std::cout << a << std::endl;
std::cout << a.list() << std::endl;
return 0;
}
現在我必須替換/修改方法工作,以元素添加到由多檢索的對象-dex指示器。
非常感謝。
您是否在某處定義了'NodeBase'。你甚至沒有告訴Node節點繼承自NodeBase – mistapink
Ups,這是通過使用基類節點列表解決它失敗的嘗試的複製粘貼錯誤。編輯並更正。 – Patxitron