如何为模板类中不同isConst类型的Iterator实现拷贝构造函数?
实现非const迭代器到const迭代器的转换(无代码重复)
核心思路
借助模板构造函数和SFINAE约束,在不拆分类、不重复代码的前提下,实现Iterator<false>到Iterator<true>的合法转换,同时禁止反向的非法转换。
修改后的完整代码
template < typename T > template < bool isConst > class ForwardList< T >::Iterator { using value_type = std::conditional_t< isConst, const T, T >; using difference_type = ptrdiff_t; using pointer = std::conditional_t< isConst, const T *, T * >; using reference = std::conditional_t< isConst, const T &, T & >; using iterator_category = std::forward_iterator_tag; friend class ForwardList< T >; // 允许不同isConst参数的Iterator互相访问私有成员 template <bool OtherConst> friend class Iterator; private: explicit Iterator(node_t *nodePtr): nodePtr_(nodePtr) {} public: Iterator() = default; Iterator(const Iterator &other) = default; ~Iterator() = default; // 模板构造函数:仅允许从非const迭代器转换到const迭代器 template <bool OtherConst> Iterator(const Iterator<OtherConst>& other, std::enable_if_t<!OtherConst && isConst, int> = 0) : nodePtr_(other.nodePtr_) {} reference operator*() const; pointer operator->() const; Iterator &operator++(); Iterator operator++(int) &; bool operator==(const Iterator &other) const; bool operator!=(const Iterator &other) const; private: node_t *nodePtr_; };
关键修改说明
友元声明:添加
template <bool OtherConst> friend class Iterator;,让不同isConst参数的Iterator实例可以互相访问私有成员(比如nodePtr_),这是转换构造函数能直接读取另一个迭代器内部指针的前提。模板构造函数+SFINAE约束:
- 模板参数
OtherConst表示传入迭代器的const属性 std::enable_if_t<!OtherConst && isConst, int> = 0是约束条件:只有当传入的是非const迭代器(!OtherConst),且当前要构造的是const迭代器(isConst)时,这个构造函数才会被编译器实例化。- 既实现了
Iterator<false>到Iterator<true>的合法转换,又禁止了Iterator<true>到Iterator<false>的非法反向转换,完全符合C++标准库迭代器的转换规则。
- 模板参数
无代码重复:所有原有成员函数(
operator*、operator++等)都无需修改,复用了全部逻辑,仅新增了必要的友元声明和转换构造函数。
使用示例
ForwardList<int> myList; // 创建非const迭代器 auto nonConstIt = myList.begin(); // 隐式转换为const迭代器(或显式构造) ForwardList<int>::Iterator<true> constIt = nonConstIt; // 以下代码会编译失败(禁止const到非const的转换) // ForwardList<int>::Iterator<false> invalidIt = constIt;
内容的提问来源于stack exchange,提问作者fromgate
相关产品推荐
相关产品推荐

