c++ - 我需要帮助返回列表前面的元素*无需*使用迭代器类(假设列表不为空)
问题描述
我坚持这一点,因为我的程序是为迭代器的用户构建的,但在这个项目中,它还要求我们返回列表中的第一个元素,而不使用迭代器。我是一个初学者级别的程序员,所以我最初的想法是回归头脑,但显然它不可能那么容易,因为所有的范围。我收到此错误:
从“List::Node”类型的表达式中对“int&”类型的引用进行无效初始化
在功能Object &raw_front()
上。
代码如下:
#ifndef LIST_H
#define LIST_H
#include <algorithm>
using namespace std;
template<typename Object>
class List {
private:
// The basic doubly linked list node.
// Nested inside of List, can be public
// because the Node is itself private
struct Node {
Object data;
Node *prev;
Node *next;
Node(const Object &d = Object{}, Node *p = nullptr, Node *n = nullptr)
: data{d}, prev{p}, next{n} {}
Node(Object &&d, Node *p = nullptr, Node *n = nullptr)
: data{std::move(d)}, prev{p}, next{n} {}
};
public:
class const_iterator {
public:
// Public constructor for const_iterator.
const_iterator() : current{nullptr} {}
// Return the object stored at the current position.
// For const_iterator, this is an accessor with a
// const reference return type.
const Object &operator*() const { return retrieve(); }
const_iterator &operator++() {
current = current->next;
return *this;
}
const_iterator operator++(int) {
const_iterator old = *this;
++(*this);
return old;
}
const_iterator &operator--() {
current = current->prev;
return *this;
}
const_iterator operator--(int) {
const_iterator old = *this;
--(*this);
return old;
}
bool operator==(const const_iterator &rhs) const { return current == rhs.current; }
bool operator!=(const const_iterator &rhs) const { return !(*this == rhs); }
protected:
Node *current;
// Protected helper in const_iterator that returns the object
// stored at the current position. Can be called by all
// three versions of operator* without any type conversions.
Object &retrieve() const { return current->data; }
// Protected constructor for const_iterator.
// Expects a pointer that represents the current position.
const_iterator(Node *p) : current{p} {}
friend class List<Object>;
};
class iterator : public const_iterator {
public:
// Public constructor for iterator.
// Calls the base-class constructor.
// Must be provided because the private constructor
// is written; otherwise zero-parameter constructor
// would be disabled.
iterator() {}
Object &operator*() { return const_iterator::retrieve(); }
// Return the object stored at the current position.
// For iterator, there is an accessor with a
// const reference return type and a mutator with
// a reference return type. The accessor is shown first.
const Object &operator*() const { return const_iterator::operator*(); }
iterator &operator++() {
this->current = this->current->next;
return *this;
}
iterator operator++(int) {
iterator old = *this;
++(*this);
return old;
}
iterator &operator--() {
this->current = this->current->prev;
return *this;
}
iterator operator--(int) {
iterator old = *this;
--(*this);
return old;
}
protected:
// Protected constructor for iterator.
// Expects the current position.
iterator(Node *p) : const_iterator{p} {}
friend class List<Object>;
};
public:
List() { init(); }
~List() {
// Place your code here.
clear( );
delete head;
delete tail;
}
List(const List &rhs) {
init();
for (auto &x : rhs)
push_back(x);
}
List &operator=(const List &rhs) {
List copy = rhs;
std::swap(*this, copy);
return *this;
}
List(List &&rhs) : theSize{rhs.theSize}, head{rhs.head}, tail{rhs.tail} {
rhs.theSize = 0;
rhs.head = nullptr;
rhs.tail = nullptr;
}
List &operator=(List &&rhs) {
std::swap(theSize, rhs.theSize);
std::swap(head, rhs.head);
std::swap(tail, rhs.tail);
return *this;
}
// Return iterator representing beginning of list.
// Mutator version is first, then accessor version.
iterator begin() { return iterator(head->next); }
const_iterator begin() const { return const_iterator(head->next); }
// Return iterator representing endmarker of list.
// Mutator version is first, then accessor version.
iterator end() { return iterator(tail); }
const_iterator end() const { return const_iterator(tail); }
// Return number of elements currently in the list.
int size() const { return theSize; }
// Return true if the list is empty, false otherwise.
bool empty() const { return size() == 0; }
void clear() {
while (!empty())
pop_front();
}
// front, back, push_front, push_back, pop_front, and pop_back
// are the basic double-ended queue operations.
Object &front() { return *begin(); }
Object &raw_front() {
// Return the element at the front of the list *without* using the iterator classes
// (You may assume the list is not empty)
// (Yes, this is bad code. I just needed something that will allow the stub to compile.)
return head ;
}
const Object &front() const { return *begin(); }
Object &back() { return *--end(); }
Object &raw_back() {
// Return the element at the end of the list *without* using the iterator classes
// (You may assume the list is not empty)
// Place your code here.
// (Yes, this is bad code. I just needed something that will allow the stub to compile.)
return tail;
}
const Object &back() const { return *--end(); }
void push_front(const Object &x) { insert(begin(), x); }
void push_back(const Object &x) { insert(end(), x); }
void raw_push_front(const Object &x) {
// insert x at the head of the list *without* using the iterator classes
// Place your code here.
Node *p = new Node(x, nullptr, head);
if(tail == nullptr)
tail = p;
head = p;
++theSize;
}
void raw_push_back(const Object &x) {
// insert x at the tail of the list *without* using the iterator classes
// Place your code here.
Node *p = new Node(x, tail, nullptr);
if(head == nullptr)
head = p;
tail = p;
++theSize;
}
void raw_insert_in_order(const Object &x) {
// insert x into the sorted list *without* using the iterator classes.
// You may assume the list is either empty or correctly sorted.
// Place your code here.
}
void push_front(Object &&x) { insert(begin(), std::move(x)); }
void push_back(Object &&x) { insert(end(), std::move(x)); }
void pop_front() { erase(begin()); }
void pop_back() { erase(--end()); }
// Insert x before itr.
iterator insert(iterator itr, const Object &x) {
Node *p = itr.current;
++theSize;
return iterator(p->prev = p->prev->next = new Node{x, p->prev, p});
}
// Insert x before itr.
iterator insert(iterator itr, Object &&x) {
Node *p = itr.current;
++theSize;
return iterator(p->prev = p->prev->next = new Node{std::move(x), p->prev, p});
}
// Erase item at itr.
iterator erase(iterator itr) {
Node *p = itr.current;
iterator retVal(p->next);
p->prev->next = p->next;
p->next->prev = p->prev;
delete p;
--theSize;
return retVal;
}
iterator erase(iterator from, iterator to) {
for (iterator itr = from; itr != to;)
itr = erase(itr);
return to;
}
void splice(iterator position, List<Object> &lst ) {
// Removes all the items from lst, add them prior to position in *this.
// You may assume lst and *this are different lists.
// **Your routine must run in constant time.**
Node *p = position.current;
theSize += lst.size();
p->prev->next = lst.head->next;
lst.head->next->prev = p->prev;
lst.tail->prev->next = p;
p->prev = lst.tail->prev;
lst.init();
}
private:
int theSize;
Node *head;
Node *tail;
void init() {
theSize = 0;
head = new Node;
tail = new Node;
head->next = tail;
tail->prev = head;
}
};
#endif
解决方案
推荐阅读
- linux - 为什么用 clonezilla 克隆的新磁盘无法启动(最终出现在 grub 提示符下)?
- c# - 安全 JSON 参数 .NET Core
- atom-editor - 如何使用 Atom 预览我的 Gitit *.page 文件?
- reactjs - 如何在 cypress 中设置本地存储
- html - 无法将变量从 Google Apps 脚本传递到 HTML,然后再次传回 GS
- google-cloud-platform - 如何允许 GCP 身份修改特定的服务帐户
- c++ - 有没有办法编写一个类似 C/C++ 函数的宏来测试是否定义了类似对象的宏并生成使用它的代码?
- elementor - Elementor Custom Widget:当用户选择媒体时,是否可以获得媒体元信息?
- shell - Yarn v1 的脚本执行 shell 的文档在哪里?
- python - 如何获取类别名称而不是 ID