我有这个类叫做“节点”。我一直在考虑将其重命名为“树”,但任何一个名称都具有同样的意义。这个类实现了一个通用的树容器。每个节点可以有任意数量的子节点。类的基本头定义如下:
template<class Elem>
class Node
{
public:
Node();
~Node();
Node(const Elem& value);
Node(const Node& rNode);
const Elem& operator*() const;
Elem& operator*();
Elem* operator->();
void operator=(const Elem& rhs);
Node* addChild(const Elem& value);
Node* addChild(Node childNode);
Node* addChild(Node* pChildNode);
HRESULT removeNode(DFSIterator<Node>& iter);
template <class Node, class List, class Iter> friend class DFSIterator;
private:
bool hasChild() const;
Node* m_pParentNode;
Elem m_value;
std::vector<Node*> m_childList;
static std::set<Node*> sNodeSet;
};
我的 DFSIterator 的标头定义是:
template<class Item,
class List = std::vector<Item*>,
class Iter = typename std::vector<Item*>::iterator>
class DFSIterator
{
public:
DFSIterator(Item& rRootNode);
~DFSIterator();
DFSIterator* begin();
DFSIterator* operator++();
Item& operator*() const;
Item* operator->() const;
bool operator!=(const DFSIterator& rhs) const;
bool isDone() const;
operator bool() const {return !isDone();}
private:
template <class Node> friend class Node;
void initChildListIterator(Item* currentNode);
bool m_bIsDone;
Item* m_pRootNode;
Item* m_pCurrentNode;
ChildListIterator<Item>* m_pCurrentListIter;
std::map<Item*, ChildListIterator<Item, List, Iter>*> m_listMap;
};
Item
是迭代器的别名Node<Elem>
。
我遇到的问题是我想为这棵树定义迭代器,用户可以以与 STL 容器类似的方式声明它。我在想像这样放置 typedef 语句typedef DFSIterator<Node<Elem>> dfs_iterator;
会很好。error C2512<Item>: no appropriate default constructor available.
但是每当我将这些语句添加到标题中时,无论我尝试去使用它,我都会收到以下错误。
所以现在,要声明一个迭代器,我必须做类似的事情,DFSIterator<Node<DataMap>> dfsIter = rRootNode.begin();
或者DFSIterator<Node<DataMap>> dfsIter(rNode);
如果我不想从树的根节点开始。我想要做的是更像Node<DataMap>::dfs_iterator it = rRootNode.begin()
. 有没有办法做到这一点,我错过了?
注意:我确实想更改有关此实现的其他一些内容。我真的不希望用户将节点元素传递给 addChild() 方法。我宁愿让用户传递一个指向节点的迭代器。