研究
我找到了 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/