У меня есть такой класс,
template <typename Node>
class BSTIteratorBase : public boost::iterator_facade<
BSTIteratorBase<Node>,
typename Node::value_type,
boost::forward_traversal_tag
>
{ ...
value_type& dereference() const
{ return const_cast<value_type&>( nodePtr_->value_ ); } // Ouch! const_iterator may modify
... };
value_type
не зависит от константность из BSTNode
учебный класс. Вот почему я должен был сохранить const_cast<value_type&>()
часть. Как я могу убедиться, что const_iterator
вернуть const_ref
но iterator
возвращает модифицируемый ref
? Вот соответствующие typedefs,
template <typename T>
class BinarySearchTree
{
public:
typedef T value_type;
typedef T& reference;
typedef const T& const_reference;
typedef BSTNode<T> node_type;
typedef BSTNode<T>& node_reference;
typedef BSTNode<T>* node_pointer;
typedef BSTIteratorBase<BSTNode<T>> iterator;
typedef BSTIteratorBase<const BSTNode<T>> const_iterator;
И класс узла,
template <typename T>
class BSTNode
{
public:
typedef T value_type;
typedef T& reference;
typedef const T& const_reference;
typedef BSTNode node_type;
typedef BSTNode* node_pointer;
// ctors, dtor
private:
template <class> friend class BSTIteratorBase;
template <class> friend class BinarySearchTree;
T value_;
node_pointer leftPtr_;
node_pointer rightPtr_;
};
Вы можете использовать metafunction что составляет value_type
если его включающий тип — const:
template<class T>
struct ValueTypeOf {
typedef typename T::value_type type;
};
template<class T>
struct ValueTypeOf<T const> {
typedef typename T::value_type const type;
};
template <typename Node>
class BSTIteratorBase : public boost::iterator_facade<
BSTIteratorBase<Node>,
typename ValueTypeOf<Node>::type,
boost::forward_traversal_tag
>
// ...
Я был бы склонен написать
typedef BSTIteratorBase<BSTNode<T>> iterator;
typedef BSTIteratorBase<const BSTNode<const T>> const_iterator;
^-- note extra const
Обратите внимание, что это красиво отражает T **
-> const T *const *
преобразование.