C++17 STL Cookbook
上QQ阅读APP看书,第一时间看更新

How to do it...

In this section, we will set up a cheap to-do list organizing structure. We do not parse user input in order to keep this program short and concentrate on std::priority_queue. So we're just filling an unordered list of to-do items with priorities and descriptions into a priority queue, and then read them out like from a FIFO queue data structure, but grouped by the priorities of the individual items.

  1. We need to include some headers first. std::priority_queue is in the header file <queue>.
      #include <iostream>
#include <queue>
#include <tuple>
#include <string>
  1. How do we store to-do items in the priority queue? The thing is, we cannot add items and additionally attach a priority to them. The priority queue will try to use the natural order of all items in the queue. We could now implement our own struct todo_item, and give it a priority number, and a string to-do description, and then implement the comparison operator < in order to make them orderable. Alternatively, we can just take std::pair, which enables us to aggregate two things in one type and implements comparison for us automatically.
      int main()
{
using item_type = std::pair<int, std::string>;
  1. We now have a new type item_type, which consists of an integer priority and a string description. So, let's instantiate a priority queue, which maintains such items.
          std::priority_queue<item_type> q;
  1. We will now fill the priority queue with different items which have different priorities. The goal is to provide an unstructured list, and then the priority queue tells us what to do in which order. If there are comics to read, and homework to do, of course, the homework must be done first. Unfortunately, std::priority_queue has no constructor, which accepts the initializer lists, which we can use to fill the queue from the beginning on. (With a vector or a normal list, it would have worked that way.) So we first define the list and insert it in the next step.
          std::initializer_list<item_type> il {
{1, "dishes"},
{0, "watch tv"},
{2, "do homework"},
{0, "read comics"},
};
  1. We can now comfortably iterate through the unordered list of to-do items and insert them step by step using the push function.
          for (const auto &p : il) {
q.push(p);
}
  1. All items are implicitly sorted, and therefore we have a queue which gives us out items with the highest priority.
          while(!q.empty()) {
std::cout << q.top().first << ": " << q.top().second << '\n';
q.pop();
}
std::cout << '\n';
}
  1. Let's compile and run our program. Indeed, it tells us, to do our homework first, and after washing the dishes, we can finally watch TV and read comics.
      $ ./main
2: do homework
1: dishes
0: watch tv
0: read comics