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

标签 c++ c++14 code-reuse const-iterator

研究

我找到了 this old answer .我想知道该解决方案是否仍然有效,或者是否有更有效的新方法。

背景

假设我有一个如下所示的迭代器(具体细节并不重要,重要的是它很大):

    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);
    };

问题

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

想法

我想到的第一个想法是在 node 类型上进行模板化,所以我可以传递 const node 使其成为 const 迭代器,但这听起来有点可疑

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

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

最佳答案

模板可能是避免代码重复的唯一方法。但我不会让类型参数保持打开状态。我会简单地使用一个 bool 参数,它被馈送到 std::conditional 以确定类型:

template<bool IsConst> class iter_impl {
  using value_type = std::conditional_t<IsConst, Node const, Node>;
};

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

struct const_iterator : iter_impl<true> {};
struct iterator : iter_impl<false> {};

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

Also I'm not sure if this use of const is one of those "const belongs to implementation specifics" case.

您使用 const Node 的事实确实是一个实现细节。但只要它为您提供记录的类型行为(容器的 const 成员的迭代器),我就不会对此强调太多。

关于c++ - 是否可以重用通常的迭代器来构建 const 迭代器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45788629/

相关文章:

android - 在 Android 4.4 和 7.0 上删除短信

c++ - 如何减少事件总线实现中的耦合

drupal - 如何使用 module_load_include 重用 Drupal 模块代码

iphone - 在不同的 UIViewControllers 中重用自定义 UITableView

iphone - iPhone 的可重用 Web 服务代码

c++ - 在Visual Studio 2017中计算AES/CCM的时间加密

c++ - 如何正确使用硬件加速的 Media Foundation Source Reader 来解码视频?

参数列表中带有省略号的 C++ Lambda

c++ - 我们能否在可能的情况下使用返回值优化,而在可能的情况下退回到移动而不是复制语义?

c++ - 可以使用对 shared_ptr 拥有的对象的引用吗?