是否可以重用通常的迭代器来构建const迭代器?

Inc*_*ble 1 c++ code-reuse const-iterator c++14

研究

我找到了这个老答案.我想知道解决方案是否仍然有效,或者是否有更新,更有效的方法.

背景

让我们假设我有一个像下面这样的迭代器(细节并不重要,只是它很大):

    class inorder_iterator : public std::iterator<std::forward_iterator_tag, token>
    {
        friend syntax_tree;

        node* current_node;
        std::stack<node*> prev_nodes;
        //std::stack<node*> visited_nodes;
        std::map<node*, bool> visited;
    public:
        inorder_iterator();

        inorder_iterator& operator++();
        inorder_iterator operator++(int);

        token& operator*();
        const token& operator*() const;

        token* operator->();
        const token* operator->() const;

        friend bool operator==(const inorder_iterator lhs, const inorder_iterator rhs);
        friend bool operator!=(const inorder_iterator lhs, const inorder_iterator rhs);

    private:
        inorder_iterator(node* current);
        node* find_leftmost_node(node* from);
    };
Run Code Online (Sandbox Code Playgroud)

问题

成员函数声明的实现具有合理的大小,但我想重用当前的迭代器来减少代码重复.

理念

想到的第一个想法就是在node类型上进行模板化,所以我可以通过const node使它成为const迭代器,但它听起来很腥

template <typename Node>
//replace every occurrence of node with Node
// and use decltype(node.tk) instead of token everywhere
Run Code Online (Sandbox Code Playgroud)

此外,我不确定这种使用const是否属于"const属于实现细节"的情况之一.

Sto*_*ica 5

模板可能是避免代码重复的唯一方法.但我不会打开类型参数.我只是使用一个布尔参数,它被输入a std::conditional以确定类型:

template<bool IsConst> class iter_impl {
  using value_type = std::conditional_t<IsConst, Node const, Node>;
};
Run Code Online (Sandbox Code Playgroud)

然后,容器的两个迭代器类型可以是几个别名,或者如果您想要真正的不同类型,则可以使用从模板继承的几个类.像这样:

struct const_iterator : iter_impl<true> {};
struct iterator : iter_impl<false> {};
Run Code Online (Sandbox Code Playgroud)

使用两个新类的好处是,您可以定义一个转换构造函数const_iterator,允许它从非const迭代器构建.这类似于标准库的行为.

此外,我不确定const的使用是否是"const属于实现细节"的情况之一.

您使用a的事实const Node确实是一个实现细节.但只要它给你记录的类型行为(容器的const成员的迭代器),我就不会对此过分强调.