1

我正在编写一个 STL 风格的“树”容器类。我目前使用具有以下习语的单个类支持 const 和非 const 迭代器:

template<typename T>
class Tree
{
public:

    using iterator = TreeIterator<T, false>;                                                        
    using const_iterator = TreeIterator<T, true>;

    // ...
};

TreeIterator就像这样:

template <typename T, bool is_const_iterator/* = true*/>
class TreeIterator : public std::iterator<std::forward_iterator_tag, T>
{    
public:

    // TreeNodePointer is either a const or non-const pointer depending on the template parameter.
    typedef typename std::conditional<is_const_iterator, const TreeNode<T>*, TreeNode<T>*>::type TreeNodePointer;

    // All the iterator interface and typedefs...

private:

    TreeNodePointer m_pointer;    // internal pointer.
};

问题是,为了保持我的“STL 风格”,操作就像insert_hintemplace_hint应该将const_iterator参数作为输入,但我需要定义一个隐式转换 from iteratortoconst_iterator才能按用户预期工作。

我很确定从 a 隐式转换为 aconst iterator应该没问题const_iterator,但我不确定在语法上如何做到这一点。对我来说,在模板(或其他机制)上设置某种条件以防止const_iterator转换为iterator.

如何定义这种转换?

4

1 回答 1

4

有两种方法可以编写隐式转换。

  1. 为它编写一个转换构造函数,const_iterator它需要一个iterator.
  2. 编写一个转换函数iterator,将其转换为const_iterator.

在这种情况下,最简单的方法可能是编写一个转换函数:

operator TreeIterator<T, true>() const { return /* ... */; }

TreeIterator<T, true>这个函数在and中都存在TreeIterator<T, false>,但如果对象已经是 a 则永远不会实际使用TreeIterator<T, true>。相反的转换是根本不可能的,因为没有为它写任何东西。

于 2015-02-19T16:46:06.897 回答