问题描述
我正在尝试制作一个 const_iterator,但我在理解它时遇到了一些麻烦。我尝试更改内容以使其正常工作,但无法编译。有人可以帮我理解我做错了什么吗? 我的代码看起来像那样 -
#include <iostream>
#include <cstring>
#include <string>
#include <functional>
#include "dummy.h"
using namespace std;
#ifndef SORT_H
#define SORT_H
template <class T>
class LinkedList {
struct Node {
Node(const T &in) : data(in) {}
T data;
Node * next;
};
Node * head;
public:
LinkedList() {
head = nullptr;
}
LinkedList(T value) {
head = new Node(value);
}
~LinkedList() {
while(head != nullptr) {
Node * curr = head -> next;
delete head;
head = curr;
}
}
class const_iterator
{
Node* m_ptr; // pointer to current node in the list
bool operator != (const const_iterator other) const {
return m_ptr != other.m_ptr;
}
public:
const_iterator() {
m_ptr = nullptr;
}
const_iterator(Node * node) {
m_ptr = node;
}
const_iterator(const const_iterator &it){
m_ptr = it.m_ptr;
}
const_iterator& operator =(const_iterator it) {
std::swap(it.m_ptr,m_ptr);
return *this;
}
const_iterator& operator ++ () {
if (m_ptr == nullptr) {
throw out_of_range("out of range");
}
m_ptr = m_ptr -> next;
return *this;
}
const_iterator operator ++ (T) {
if (m_ptr == nullptr) {
throw out_of_range("out of range");
}
const_iterator temp(*this);
m_ptr = m_ptr -> next;
return temp;
}
bool operator == (const const_iterator other) const {
return m_ptr == other.m_ptr;
}
T& operator*() const {
return *m_ptr;
}
operator bool() {
return m_ptr != nullptr;
};
bool is_in_list(LinkedList<T>::const_iterator it){
Node * curr = head;
while(curr != nullptr) {
if (curr == it){
return true;
} else {
curr = curr->next;
}
}
return false;
}
LinkedList& operator =(LinkedList list) {
std::swap(list.head,head);
return *this;
}
Node * nodecopy(Node * head) {
if (head == nullptr) {
return nullptr;
}
Node * copied_node = new Node(head -> data);
copied_node -> data = head -> data;
copied_node -> next = nodecopy(head -> next);
return copied_node;
}
LinkedList(const LinkedList &list){
head = nodecopy(list.head);
}
template<typename B>
LinkedList filter(LinkedList &list,B pred) {
LinkedList <T> new_list(list);
Node * curr = list.head;
while (curr) {
if (!(pred(curr -> data))) {
new_list.remove(curr -> data);
}
curr = curr -> next;
}
std::cout << "Getting out of filter" << std::endl;
return new_list;
}
template<typename A>
LinkedList apply(A func) {
LinkedList <T> new_list;
Node * curr = head;
while (curr) {
new_list.insert(func(curr -> data));
std::cout << "Putting into new list: " << func(curr -> data) << std::endl;
curr = curr -> next;
}
std::cout << "Getting out of apply" << std::endl;
return new_list;
}
int length() {
// std::cout << "DEBUG length 1" << std::endl;
int counter = 0;
Node * tmp = head;
// std::cout << "DEBUG length 2" << std::endl;
while( tmp != nullptr ) {
// std::cout << "DEBUG length 3" << std::endl;
counter++;
tmp = tmp -> next;
}
return counter;
}
void insert(T value) {
// Add first node
if (head == nullptr) {
std::cout << "Add first node" << std::endl;
head = new Node(value);
head->next = nullptr;
return;
}
Node *curr = head;
// check if should be new head (when new value smaller than current head) -> add new head
if (value <= head->data) {
// add new head
std::cout << "add new head" << std::endl;
Node * new_head = new Node(value);
new_head -> next = head;
head = new_head;
return;
}
while (curr != nullptr) {
if (curr->next == nullptr && value >= curr->data) {
// add new tail
std::cout << "add new tail" << std::endl;
Node * new_node = new Node(value);
curr -> next = new_node;
new_node -> next = nullptr;
return;
} else if (value >= curr->data && value <= curr->next->data) {
// add new node between those two
std::cout << "add new node between those two" << std::endl;
Node * new_node = new Node(value);
Node * temp_ptr = curr -> next;
curr -> next = new_node;
new_node -> next = temp_ptr;
return;
} else {
curr = curr->next;
}
}
}
void remove(const_iterator it) {
// Todo: Check if delete all accurancies
if (!is_in_list(it)){
return;
}
// handle the head
if (head == it) {
if (head->next != nullptr) {
// head is not single node
Node * temp_ptr = head->next;
delete head;
head = temp_ptr;
return;
} else {
// head is single node
delete head;
head = nullptr;
return;
}
}
Node * curr = head;
Node * prev = head;
while (curr != nullptr){
if (curr == it){
// as we are already handled the head case,// at this point we kNow that curr != head.
prev->next = curr->next;
delete curr;
return;
} else {
prev=curr;
curr=curr->next;
}
}
}
void print() {
Node * curr = head;
while (curr != nullptr) {
cout << curr -> data << endl;
curr = curr -> next;
}
}
Node * begin() const {
return head;
}
Node * end() const {
Node * curr = head;
while (curr->next != nullptr){
curr = curr->next;
}
return curr;
}
};
#endif
我的主要看起来像那样-
#include <iostream>
#include "sortedList.h"
#include "dummy.h"
bool func(Dummy num) {
int number = num.get();
if (number % 2 != 0) {
return false;
}
return true;
}
string getLen(string str)
{
return std::to_string(str.length());
}
using std::string;
int main() {
std::cout << "Hello,World!" << std::endl;
LinkedList<string> lst1 = LinkedList<string>();
lst1.insert("Charlie");
lst1.insert("Bob");
lst1.insert("Alice");
lst1.insert("Donald");
lst1.print();
LinkedList<string> lst2 = lst1;
lst2 = lst2.apply(getLen);
lst2.print();
LinkedList<string>::const_iterator it = lst2.begin();
cout << *it << endl << endl;
++it;
lst2.remove(it);
lst2.print();
return 0;
}
In file included from C:\Users\User\CLionProjects\ex2.2\main.cpp:2:
C:\Users\User\CLionProjects\ex2.2\sortedList.h: In instantiation of 'class LinkedList<std::__cxx11::basic_string<char> >::const_iterator':
C:\Users\User\CLionProjects\ex2.2\main.cpp:40:44: required from here
C:\Users\User\CLionProjects\ex2.2\sortedList.h:79:24: error: postfix 'LinkedList<T>::const_iterator LinkedList<T>::const_iterator::operator++(T) [with T = std::__cxx11::basic_string<char>]' must have 'int' as its argument
const_iterator operator ++ (T) {
^~~~~~~~
C:\Users\User\CLionProjects\ex2.2\sortedList.h: In instantiation of 'T& LinkedList<T>::const_iterator::operator*() const [with T = std::__cxx11::basic_string<char>]':
C:\Users\User\CLionProjects\ex2.2\main.cpp:41:18: required from here
C:\Users\User\CLionProjects\ex2.2\sortedList.h:92:21: error: invalid initialization of reference of type 'std::__cxx11::basic_string<char>&' from expression of type 'LinkedList<std::__cxx11::basic_string<char> >::Node'
return *m_ptr;
解决方法
我做错了什么?
self_type operator++() { self_type i = *this; ptr_++; return i; }
这行不通。 ptr_++
会将指针移动到 array 的下一个元素...除了在这种情况下没有数组。您不是在为数组编写迭代器,而是在为链表编写迭代器。
您需要一个指向节点的指针,而不是指向元素的指针。要移动到下一个节点,您需要 ptr = ptr->next
。
至于编译错误,看错误信息,错误在哪里。您还没有显示 return *head;
的位置,但让我们看看另一个:
Node * head;
...
LinkedList<T>::const_iterator it
...
if (head == it) {
您正在将指向节点的指针与迭代器进行比较。为什么你认为这会奏效?你期望结果是什么?错误的解决方法是不这样做。