【问题标题】:Queue implementation using std::forward_list returning an error使用 std::forward_list 返回错误的队列实现
【发布时间】:2020-06-13 08:20:54
【问题描述】:

返回此运行时错误

$/usr/bin/ld: QueueusingSLL: _ZSt4cout: invalid version 2 (max 0)

$/usr/bin/ld: QueueusingSLL: error adding symbols: bad value 
collect2: error: ld returned 1 exit status

另外,如何从类成员函数返回迭代器? 请参阅代码中的auto iterator() 函数。

源代码

#include<iostream>     // std::cout
#include<forward_list> // std::singly linked list
#include<iterator>     //// std::iterator,next(is a random iterator)
//#include <algorithm> // std::for_each loop
using namespace std;

class Queue
{
private:
   forward_list<int> list;

public:
   Queue()
   {}

   Queue(int firstElem) {
      enqueue(firstElem);
   }

   //Return the size of Queue
   int size()
   {
      forward_list<int>::iterator first = list.begin();
      forward_list<int>::iterator last = list.end();
      return std::distance(first, last);
   }

   //Return whether or not the queue us empty
   void isEmpty()
   {
      std::cout << "Queue " << (list.empty() ? "is empty" : "is not empty") << std::endl;
   }

   // Peek the top of the stack without removing an element
   // Returns 0 if queue is empty.
   int peek()
   {
      if (list.empty() == 1)
         return 0;
      return list.front();
   }

   //Add an element at back(end or tail) of queue:enqueue
   void enqueue(int Elem)
   {
      auto pos = list.begin();
      while (std::next(pos) != list.end()) ++pos;
      list.insert_after(pos, Elem);
   }

   //Remove an element from front of queue:dequeue
   int dequeue()
   {
      if (list.empty() == 1) return 0;
      list.pop_front();
      return 1; //1 means success
   }

   void display()
   {
      cout << endl << "Elements in Queue x";
      for (forward_list<int>::iterator i = list.begin(); i != list.end(); i++)
      {
         cout << endl << "\t" << *i;
      }
      cout << endl << endl;
   }

   /*auto iterator()
    {
        return list.iterator();
    }*/
};


int main()
{
   Queue Q1, Q2(5);
   Q1.isEmpty();
   Q2.isEmpty();
   cout << endl << "sizeofQ1   " << Q1.size() << endl << "sizeofQ2     " << Q2.size() << endl << endl;
   Q1.enqueue(10);
   Q1.enqueue(20);
   Q1.enqueue(30);
   Q1.enqueue(40);
   Q1.enqueue(50);
   Q1.enqueue(60);
   Q1.display();
   Q2.display();
   cout << endl << "sizeofQ1   " << Q1.size() << endl << endl;
   Q1.dequeue();
   Q1.dequeue();
   Q1.display();
   cout << endl << "sizeofQ1   " << Q1.size() << endl << endl;
   return 0;
}

【问题讨论】:

    标签: c++ c++11 data-structures iterator queue


    【解决方案1】:

    首先,如果你想插入容器的末端,最好使用std::vector,而不是std::forward_list。然后只需使用std::vector::push_back 或std::vector::emplace_back。要获取第一个和最后一个元素,请分别使用std::vector::front 和std::vector::back。


    对于您的问题:您的 enqueue 函数无法处理 list 空案例。你需要

    void enqueue(int Elem)
    {
       if (list.empty())  // for the empty list case
       {
          list.push_front(Elem);
          return; // done here
       }
    
       auto pos = list.begin();
       while (std::next(pos) != list.end())
          ++pos;
       list.insert_after(pos, Elem);
    }
    

    如何从类成员函数返回迭代器?

    与标准容器一样,您需要通过提供合适的成员来返回 begin 和 end 迭代器。比如

    auto begin() const noexcept {
       return list.begin();
    }
    
    auto end() const noexcept {
       return list.end();
    }
    

    但是,auto 只有在 之后才有可能返回。在 中,您需要明确提及返回类型。感谢trailing return,您可以通过它

    auto begin() const noexcept -> decltype(list.begin()) // trailing return
    {
       return list.begin();
    }
    
    auto end() const noexcept -> decltype(list.end()) // trailing return
    {
       return list.end();
    }
    

    作为旁注,please do not practice with using namespace std;

    【讨论】:

    • 好答案。我只想明确指出开始和结束是列表的两种方法。 ".iterator()" 不是。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-02
    • 2012-02-05
    • 2012-07-17
    • 2011-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多