自定义双向链表中自定义迭代器的取消引用运算符,未找到二元运算符
Dereference operator for custom iterator in custom doubly linked list, binary operator not found
我在容器 class 中实现了一个带有嵌套自定义迭代器的通用双向链表容器。我的问题是编译时我得到:
Error C2678 binary '*': no operator found which takes a left-hand operand of type 'const List::ListIter' (or there is no acceptable conversion)
此错误指向例如在第 246 行尝试取消引用迭代器时。迭代器的operator*
在迭代器class中实现,但编译器似乎无法找到重载。
构建时其他一切似乎都编译得很好
using std::cout;
template<class T> class List {
template<class T>
class Node;
public:
template <class T>
class Link {
public:
friend class List<T>;
Link* _next, *_prev;
Link(Link *n, Link *p) : _next(n), _prev(p) {}
Node<T>* Next() { return static_cast<Node<T>*>(_next); }
Node<T>* Prev() { return static_cast<Node<T>*>(_next); }
};
template<class T>
class Node :public Link<T> {
public:
friend class List<T>;
Node(const T& data = NULL, Link<T> *n = NULL, Link<T> *p = NULL) :_data(data), Link<T>(n, p) {}
T _data;
};
public:
template<class T> class ListIter {
public:
typedef ptrdiff_t difference_type;
typedef T value_type;
typedef T* pointer;
typedef T& reference;
typedef std::bidirectional_iterator_tag iterator_category;//behvöber fixas
ListIter(Node<T>* p) {
_ptr = p;
}
ListIter() {
_ptr = nullptr;
}
ListIter(const ListIter& other) {
_ptr = other._ptr;
}
ListIter& operator=(const ListIter& other) {
if (_ptr == other._ptr) {
return *this;
}
else {
_ptr = other._ptr;
return *this;
}
}
T & operator*() {
return _ptr->_data;
}
T* operator->() {
return &_ptr->_data;
}
ListIter& operator++() {
_ptr = static_cast<Node<T>*>(_ptr->_next);
return *this;
}
ListIter& operator--() {
_ptr = static_cast<Node<T>*>(_ptr->Prev());
return *this;
}
ListIter operator++(int) {
ListIter temp(*this);
_ptr = static_cast<Node<T>*>(_ptr->_next);
return temp;
}
ListIter operator--(int) {
ListIter temp(*this);
_ptr = static_cast<Node<T>*>(_ptr->Prev());
return temp;
}
private:
Node<T>* _ptr;
};
using iterator = ListIter<T>;
~List() {
int counter = 0;
Link<T> *curr = _head;
while (curr != nullptr)
{
Link<T> *remove = curr;
curr = curr->_next;
delete remove;
counter++;
}
cout << "removed" << counter << std::endl;
}
List() :_head(nullptr) {};
List(const List& other) {
if (other._head == nullptr) {
_head = nullptr;
}
_head = new Node<T>(other._head->_data);
Node<T> *tempOther = _head->Next();
while (tempOther != other._head) {
push_back(tempOther->_data);
tempOther = tempOther->Next();
}
}
List(List&& other) {
_head = other._head;
other._head = nullptr;
}
List(const char* other) {
int i = 0;
while (other[i] != '[=10=]') {
push_front(other[i]);
i++;
}
}
List& operator=(const List* other) {
if (*this == *other) {
return *this;
}
else {
if (other->_head != NULL) {
Link<T> *curr = _head;
while (curr != nullptr)
{
Link<T> *remove = curr;
curr = curr->_next;
delete remove;
}
_head = new Node<T>(other->_head->_data);
if (other->_head->Prev() != NULL) {
Node<T> *prev = other->_head->Prev();
while (prev != NULL) {
push_back(prev->_data);
prev = prev->Prev();
}
}
other->~List();
}
else {
throw std::exception("list empty");
}
}
return *this;
}
List& operator=(List&& other) {
while (_head->_next != _head)
{
Link<T> *remove = _head->_next;
_head->_next = remove->_next;
delete remove;
}
delete _head;
_head = other._head;
return *this;
}
T& front() {
if (_head->_next != NULL) {
return _head->Next()->_data;
}
else {
throw std::exception("list is empty");
}
}
T& back() {
if (!empty()) {
Node<T> *last = _head->Prev();
return last->_data;
}
else {
throw std::exception("list is empty");
}
}
iterator begin() const {
return ListIter<T>(_head);
}
iterator end() const {
return ListIter<T>(_head->Prev());
}
bool empty() const noexcept {
if (_head == NULL) {
return true;
}
else {
return false;
}
}
size_t size() const noexcept {
size_t counter = 0;
if (empty()) {
return 0;
}
else if (_head->Next() == _head->Prev()) {
return 1;
}
else {
Link<T> *last = _head->_next;
while (last != _head) {
last = last->_next;
counter++;
}
}
return counter;
}
iterator insert(const iterator& pos, const T& value) {
if (empty()) {
throw std::exception("list empty");
}
else {
Node<T> prev = *pos->Prev();
Node<T> newNode = new Node<T>(value, *pos, prev);
prev->_next = newNode;
*pos->_prev = newNode;
}
}
ListIter erase(const iterator& pos) {
Link<T> next = (*pos)->_next;
Link<T> prev = (*pos)->_prev;
next._prev = prev;
prev._next = next;
delete *pos;
}
void push_front(const T& value) {
if (empty()) {
_head = new Node<T>(value);
}
else if (size() == 1) {
Node<T> *newHead = new Node<T>(value, _head, _head);
_head->_next = newHead;
_head->_prev = newHead;
_head = newHead;
}
else {
Node<T> *newhead = new Node<T>(value, _head, _head->Prev());
_head = newhead;
}
}
void push_back(const T& value) {
if (empty()) {
_head = new Node<T>(value);
}
else if (size() == 1) {
Node<T> *last = new Node<T>(value, _head, _head);
_head->_next = last;
_head->_prev = last;
}
else {
Link<T> *last = _head->Prev();
Node<T> *newLast = new Node<T>(value, _head, last);
last->_next = newLast;
}
}
void pop_back() {
if (empty()) {
throw std::exception("list is empty");
}
else {
Link<T> *last = _head->Prev();
Link<T> *beforeLast = last->Prev();
beforeLast->_next = _head;
delete last;
}
}
void pop_front() {
if (empty()) {
throw std::exception("list is empty");
}
else {
Link<T> *newFront = _head->Next();
Link<T> *temp = _head->Prev();
temp->_next = newFront;
delete _head;
_head = static_cast<Node<T>*>(newFront);
}
}
friend bool operator==(const List& lhs, const List& rhs) {
bool result = true;
if (lhs.size() == rhs.size()) {
if (!lhs.empty()) {
Node<T> *lhsNode = lhs._head;
Node<T> *rhsNode = rhs._head;
while (lhsNode->_next != NULL && rhsNode->Next() != NULL) {
if (lhsNode->_data != rhsNode->_data) {
result = false;
}
}
}
else {
throw std::exception("list empty");
}
}
else {
result = false;
}
return result;
}
friend std::ostream& operator<<(std::ostream& cout, const List& other);
void Check() const {
/*assert(Invariant());*/
}
template< class T>
void swap(List<T>& lhs, List<T>& rhs) {
Node<T> temp = rhs._head;
rhs._head = lhs._head;
lhs._head = temp;
}
private:
Node<T> *_head;
};
我只需要访问取消引用的迭代器应该提供的值。
在 insert
和 erase
中你有 const iterator& pos
。由于您通过引用传递给常量,因此迭代器是 const
。您的 operator*
未标记为 const
因此您不能在常量对象上使用它。您要么需要提供 const
重载,要么从函数参数中删除 const
。
我在容器 class 中实现了一个带有嵌套自定义迭代器的通用双向链表容器。我的问题是编译时我得到:
Error C2678 binary '*': no operator found which takes a left-hand operand of type 'const List::ListIter' (or there is no acceptable conversion)
此错误指向例如在第 246 行尝试取消引用迭代器时。迭代器的operator*
在迭代器class中实现,但编译器似乎无法找到重载。
构建时其他一切似乎都编译得很好
using std::cout;
template<class T> class List {
template<class T>
class Node;
public:
template <class T>
class Link {
public:
friend class List<T>;
Link* _next, *_prev;
Link(Link *n, Link *p) : _next(n), _prev(p) {}
Node<T>* Next() { return static_cast<Node<T>*>(_next); }
Node<T>* Prev() { return static_cast<Node<T>*>(_next); }
};
template<class T>
class Node :public Link<T> {
public:
friend class List<T>;
Node(const T& data = NULL, Link<T> *n = NULL, Link<T> *p = NULL) :_data(data), Link<T>(n, p) {}
T _data;
};
public:
template<class T> class ListIter {
public:
typedef ptrdiff_t difference_type;
typedef T value_type;
typedef T* pointer;
typedef T& reference;
typedef std::bidirectional_iterator_tag iterator_category;//behvöber fixas
ListIter(Node<T>* p) {
_ptr = p;
}
ListIter() {
_ptr = nullptr;
}
ListIter(const ListIter& other) {
_ptr = other._ptr;
}
ListIter& operator=(const ListIter& other) {
if (_ptr == other._ptr) {
return *this;
}
else {
_ptr = other._ptr;
return *this;
}
}
T & operator*() {
return _ptr->_data;
}
T* operator->() {
return &_ptr->_data;
}
ListIter& operator++() {
_ptr = static_cast<Node<T>*>(_ptr->_next);
return *this;
}
ListIter& operator--() {
_ptr = static_cast<Node<T>*>(_ptr->Prev());
return *this;
}
ListIter operator++(int) {
ListIter temp(*this);
_ptr = static_cast<Node<T>*>(_ptr->_next);
return temp;
}
ListIter operator--(int) {
ListIter temp(*this);
_ptr = static_cast<Node<T>*>(_ptr->Prev());
return temp;
}
private:
Node<T>* _ptr;
};
using iterator = ListIter<T>;
~List() {
int counter = 0;
Link<T> *curr = _head;
while (curr != nullptr)
{
Link<T> *remove = curr;
curr = curr->_next;
delete remove;
counter++;
}
cout << "removed" << counter << std::endl;
}
List() :_head(nullptr) {};
List(const List& other) {
if (other._head == nullptr) {
_head = nullptr;
}
_head = new Node<T>(other._head->_data);
Node<T> *tempOther = _head->Next();
while (tempOther != other._head) {
push_back(tempOther->_data);
tempOther = tempOther->Next();
}
}
List(List&& other) {
_head = other._head;
other._head = nullptr;
}
List(const char* other) {
int i = 0;
while (other[i] != '[=10=]') {
push_front(other[i]);
i++;
}
}
List& operator=(const List* other) {
if (*this == *other) {
return *this;
}
else {
if (other->_head != NULL) {
Link<T> *curr = _head;
while (curr != nullptr)
{
Link<T> *remove = curr;
curr = curr->_next;
delete remove;
}
_head = new Node<T>(other->_head->_data);
if (other->_head->Prev() != NULL) {
Node<T> *prev = other->_head->Prev();
while (prev != NULL) {
push_back(prev->_data);
prev = prev->Prev();
}
}
other->~List();
}
else {
throw std::exception("list empty");
}
}
return *this;
}
List& operator=(List&& other) {
while (_head->_next != _head)
{
Link<T> *remove = _head->_next;
_head->_next = remove->_next;
delete remove;
}
delete _head;
_head = other._head;
return *this;
}
T& front() {
if (_head->_next != NULL) {
return _head->Next()->_data;
}
else {
throw std::exception("list is empty");
}
}
T& back() {
if (!empty()) {
Node<T> *last = _head->Prev();
return last->_data;
}
else {
throw std::exception("list is empty");
}
}
iterator begin() const {
return ListIter<T>(_head);
}
iterator end() const {
return ListIter<T>(_head->Prev());
}
bool empty() const noexcept {
if (_head == NULL) {
return true;
}
else {
return false;
}
}
size_t size() const noexcept {
size_t counter = 0;
if (empty()) {
return 0;
}
else if (_head->Next() == _head->Prev()) {
return 1;
}
else {
Link<T> *last = _head->_next;
while (last != _head) {
last = last->_next;
counter++;
}
}
return counter;
}
iterator insert(const iterator& pos, const T& value) {
if (empty()) {
throw std::exception("list empty");
}
else {
Node<T> prev = *pos->Prev();
Node<T> newNode = new Node<T>(value, *pos, prev);
prev->_next = newNode;
*pos->_prev = newNode;
}
}
ListIter erase(const iterator& pos) {
Link<T> next = (*pos)->_next;
Link<T> prev = (*pos)->_prev;
next._prev = prev;
prev._next = next;
delete *pos;
}
void push_front(const T& value) {
if (empty()) {
_head = new Node<T>(value);
}
else if (size() == 1) {
Node<T> *newHead = new Node<T>(value, _head, _head);
_head->_next = newHead;
_head->_prev = newHead;
_head = newHead;
}
else {
Node<T> *newhead = new Node<T>(value, _head, _head->Prev());
_head = newhead;
}
}
void push_back(const T& value) {
if (empty()) {
_head = new Node<T>(value);
}
else if (size() == 1) {
Node<T> *last = new Node<T>(value, _head, _head);
_head->_next = last;
_head->_prev = last;
}
else {
Link<T> *last = _head->Prev();
Node<T> *newLast = new Node<T>(value, _head, last);
last->_next = newLast;
}
}
void pop_back() {
if (empty()) {
throw std::exception("list is empty");
}
else {
Link<T> *last = _head->Prev();
Link<T> *beforeLast = last->Prev();
beforeLast->_next = _head;
delete last;
}
}
void pop_front() {
if (empty()) {
throw std::exception("list is empty");
}
else {
Link<T> *newFront = _head->Next();
Link<T> *temp = _head->Prev();
temp->_next = newFront;
delete _head;
_head = static_cast<Node<T>*>(newFront);
}
}
friend bool operator==(const List& lhs, const List& rhs) {
bool result = true;
if (lhs.size() == rhs.size()) {
if (!lhs.empty()) {
Node<T> *lhsNode = lhs._head;
Node<T> *rhsNode = rhs._head;
while (lhsNode->_next != NULL && rhsNode->Next() != NULL) {
if (lhsNode->_data != rhsNode->_data) {
result = false;
}
}
}
else {
throw std::exception("list empty");
}
}
else {
result = false;
}
return result;
}
friend std::ostream& operator<<(std::ostream& cout, const List& other);
void Check() const {
/*assert(Invariant());*/
}
template< class T>
void swap(List<T>& lhs, List<T>& rhs) {
Node<T> temp = rhs._head;
rhs._head = lhs._head;
lhs._head = temp;
}
private:
Node<T> *_head;
};
我只需要访问取消引用的迭代器应该提供的值。
在 insert
和 erase
中你有 const iterator& pos
。由于您通过引用传递给常量,因此迭代器是 const
。您的 operator*
未标记为 const
因此您不能在常量对象上使用它。您要么需要提供 const
重载,要么从函数参数中删除 const
。