前向迭代器 - Const 版本问题
Forward Iterator - Const version issue
我似乎无法解决这个问题。我已经实现了一个模板化的前向迭代器,我也想在我的 ForwardList class 中将其用作 const_iterator。到目前为止我尝试的是使用别名,并将 const
作为模板参数插入,但它似乎不起作用。
这是我的前向迭代器:
template<typename T>
class forward_iterator {
private:
Node<T>* m_iterator;
public:
using value_type = T;
using reference = T&;
using pointer = value_type*;
using iterator_category = std::forward_iterator_tag;
using difference_type = std::ptrdiff_t;
constexpr forward_iterator(Node<T>* forw_iter) : m_iterator{ forw_iter } {}
constexpr Node<T>* getNodeAddress() const noexcept { return m_iterator; }
constexpr Node<T>* getNodeNextAddress() const noexcept { return m_iterator->next; }
constexpr reference operator*() const noexcept { return m_iterator->data; }
constexpr pointer operator->() const noexcept { return m_iterator; }
constexpr forward_iterator& operator++() noexcept {
m_iterator = m_iterator->next;
return *this;
}
constexpr forward_iterator operator++(int) noexcept {
forward_iterator tmp(*this);
m_iterator = m_iterator->next;
return tmp;
}
constexpr friend bool operator== (const forward_iterator& first, const forward_iterator& second) noexcept { return (first.m_iterator == second.m_iterator); }
constexpr friend bool operator!=(const forward_iterator& first, const forward_iterator& second) noexcept { return !(first.m_iterator == second.m_iterator); }
};
这就是我在转发列表中使用别名的方式 class:
template<typename Type>
class ForwardList {
private:
Node<Type>* m_head;
Node<Type>* m_tail;
std::size_t m_size{};
public:
using value_type = Type;
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
using reference = value_type&;
using const_reference = const value_type&;
using pointer = Type*;
using const_pointer = const pointer;
using iterator = forward_iterator<value_type>;
using const_iterator = forward_iterator<const Type>;
这是节点结构:
template<typename T>
struct Node {
T data;
Node* next;
Node() = default;
constexpr explicit Node(const T& data)
: data{ data } {}
};
不过,我在使用 const_iterator 时遇到错误。例如:
constexpr const_iterator cbegin() const noexcept {
return const_iterator(m_head);
}
^ 在迭代器函数中,我得到“Cannot convert from container::Node<Type> *const to container::forward_iterator<const Type>
.
另一个例子:
constexpr iterator emplace_after(const_iterator position, Args...args)
^ 在emplace_after中,我无法传入一个普通的“list.begin()”迭代器,因为找不到函数。我必须改为传递“list.cbegin()”。
如果有人能帮助理解问题所在,那就太好了。
下面使您的 forward_iterator<const T>
指向 Node<const T>
,而 forward_iterator<T>
将指向 Node<T>
。无论 T
是否是 const
本身,两者都应指向 Node<T>
:
template<typename T>
class forward_iterator {
private:
Node<T>* m_iterator;
我发现在容器 class 模板中将迭代器创建为 class 模板更容易,这样原始的 T
就可用了。如果您想在 class 之外执行此操作,您可以将模板参数添加到迭代器模板:
template<typename OrigT, typename T>
class forward_iterator {
private:
Node<OrigT>* m_iterator;
public:
constexpr forward_iterator_impl(Node<OrigT>* forw_iter) : m_iterator{ forw_iter } {}
...
并且在容器class模板中:
template<typename Type>
class ForwardList {
public:
...
using iterator = forward_iterator<value_type, value_type>;
using const_iterator = forward_iterator<value_type, const value_type>;
通过将节点和迭代器都移动到容器中 class。它变得更容易得到它的权利。 Demo
我似乎无法解决这个问题。我已经实现了一个模板化的前向迭代器,我也想在我的 ForwardList class 中将其用作 const_iterator。到目前为止我尝试的是使用别名,并将 const
作为模板参数插入,但它似乎不起作用。
这是我的前向迭代器:
template<typename T>
class forward_iterator {
private:
Node<T>* m_iterator;
public:
using value_type = T;
using reference = T&;
using pointer = value_type*;
using iterator_category = std::forward_iterator_tag;
using difference_type = std::ptrdiff_t;
constexpr forward_iterator(Node<T>* forw_iter) : m_iterator{ forw_iter } {}
constexpr Node<T>* getNodeAddress() const noexcept { return m_iterator; }
constexpr Node<T>* getNodeNextAddress() const noexcept { return m_iterator->next; }
constexpr reference operator*() const noexcept { return m_iterator->data; }
constexpr pointer operator->() const noexcept { return m_iterator; }
constexpr forward_iterator& operator++() noexcept {
m_iterator = m_iterator->next;
return *this;
}
constexpr forward_iterator operator++(int) noexcept {
forward_iterator tmp(*this);
m_iterator = m_iterator->next;
return tmp;
}
constexpr friend bool operator== (const forward_iterator& first, const forward_iterator& second) noexcept { return (first.m_iterator == second.m_iterator); }
constexpr friend bool operator!=(const forward_iterator& first, const forward_iterator& second) noexcept { return !(first.m_iterator == second.m_iterator); }
};
这就是我在转发列表中使用别名的方式 class:
template<typename Type>
class ForwardList {
private:
Node<Type>* m_head;
Node<Type>* m_tail;
std::size_t m_size{};
public:
using value_type = Type;
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
using reference = value_type&;
using const_reference = const value_type&;
using pointer = Type*;
using const_pointer = const pointer;
using iterator = forward_iterator<value_type>;
using const_iterator = forward_iterator<const Type>;
这是节点结构:
template<typename T>
struct Node {
T data;
Node* next;
Node() = default;
constexpr explicit Node(const T& data)
: data{ data } {}
};
不过,我在使用 const_iterator 时遇到错误。例如:
constexpr const_iterator cbegin() const noexcept {
return const_iterator(m_head);
}
^ 在迭代器函数中,我得到“Cannot convert from container::Node<Type> *const to container::forward_iterator<const Type>
.
另一个例子:
constexpr iterator emplace_after(const_iterator position, Args...args)
^ 在emplace_after中,我无法传入一个普通的“list.begin()”迭代器,因为找不到函数。我必须改为传递“list.cbegin()”。
如果有人能帮助理解问题所在,那就太好了。
下面使您的 forward_iterator<const T>
指向 Node<const T>
,而 forward_iterator<T>
将指向 Node<T>
。无论 T
是否是 const
本身,两者都应指向 Node<T>
:
template<typename T>
class forward_iterator {
private:
Node<T>* m_iterator;
我发现在容器 class 模板中将迭代器创建为 class 模板更容易,这样原始的 T
就可用了。如果您想在 class 之外执行此操作,您可以将模板参数添加到迭代器模板:
template<typename OrigT, typename T>
class forward_iterator {
private:
Node<OrigT>* m_iterator;
public:
constexpr forward_iterator_impl(Node<OrigT>* forw_iter) : m_iterator{ forw_iter } {}
...
并且在容器class模板中:
template<typename Type>
class ForwardList {
public:
...
using iterator = forward_iterator<value_type, value_type>;
using const_iterator = forward_iterator<value_type, const value_type>;
通过将节点和迭代器都移动到容器中 class。它变得更容易得到它的权利。 Demo