首页 > 解决方案 > 我需要帮助返回列表前面的元素*无需*使用迭代器类(假设列表不为空)

问题描述

我坚持这一点,因为我的程序是为迭代器的用户构建的,但在这个项目中,它还要求我们返回列表中的第一个元素,而不使用迭代器。我是一个初学者级别的程序员,所以我最初的想法是回归头脑,但显然它不可能那么容易,因为所有的范围。我收到此错误:

从“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

标签: c++list

解决方案


推荐阅读