0

I'm trying to understand the code below from

How to iterate over a priority_queue?

I gather that since HackedQueue is deriving privately from priority_queue, it can access its privates. So, I assume that *&HackedQueue::c returns the address of the base class object, and its called for q. Not fully clear, though, and even more how it's a valid syntax.


Mentioning priority_queue, I was wondering if there's still no cleaner workaround. For example, the 4th c'tor on this link

priority_queue( const Compare& compare, Container&& cont );

https://en.cppreference.com/w/cpp/container/priority_queue/priority_queue

seems to provide a container to work with and not as read only input. I don't see it though in visual studio header file, and I'm not clear what is &&.


Related, I don't understand opposing questions such as why I need access to the private container, it's not made for that. Well, how do you debug a priority queue, where the basic need is to print its elements?


#include <queue>
#include <cstdlib>
#include <iostream>
using namespace std;

template <class T, class S, class C>
S& Container(priority_queue<T, S, C>& q) {
    struct HackedQueue : private priority_queue<T, S, C> {
        static S& Container(priority_queue<T, S, C>& q) {
            return q.*&HackedQueue::c;
        }
    };
    return HackedQueue::Container(q);
}

int main()
{
    priority_queue<int> pq;
    vector<int> &tasks = Container(pq);

    cout<<"Putting numbers into the queue"<<endl;
    for(int i=0;i<20;i++){
        int temp=rand();
        cout<<temp<<endl;
        pq.push(temp);
    }

    cout<<endl<<"Reading numbers in the queue"<<endl;
    for(vector<int>::iterator i=tasks.begin();i!=tasks.end();i++)
        cout<<*i<<endl;

    cout<<endl<<"Taking numbers out of the queue"<<endl;
    while(!pq.empty()){
        int temp=pq.top();
        pq.pop();
        cout<<temp<<endl;
    }

    return 0;
}
Zohar Levi
  • 614
  • 6
  • 16
  • It's `q.*(&HackedQueue::c)` - syntax for using pointer to member. But I'm not even attempting to understand what in Eldritch horror happened here. – Yksisarvinen Sep 01 '21 at 11:28
  • 2
    One question per stackoverflow.com question, please. Can you [edit] your question and ask a ***single*** question, for which a ***single*** answer can be given? `&&` is an rvalue reference, see your C++ textbook for more information and a detailed explanation (Stackoverflow isn't really a replacement for a C++ textbook, if there's something ***specific*** about any of these topics that's unclear, you can ask and explain exactly what you'd like to clarify, but for general tutorials and explanations, we refer people to their textbooks). – Sam Varshavchik Sep 01 '21 at 11:30
  • `&HackedQueue::c` is a pointer-to-member - `c` is the underlying container member of `priority_queue`. `.*` is the "dereference pointer-to-member" operator. These contortions are for accessing a protected member of a different instance of the same class. – molbdnilo Sep 01 '21 at 11:30
  • Dupes: (1) https://stackoverflow.com/q/6586205/817643 (2) https://stackoverflow.com/q/5590978/817643 – StoryTeller - Unslander Monica Sep 01 '21 at 11:33
  • What is your question here? Are you asking what does that code means __or__ are you asking about `how do you debug a priority queue, where the basic need is to print its elements?` __or__ what does `&&` means? Please do not ask multiple question. `Mentioning priority_queue, I was wondering if...` Is this part relevant _to your question_ or can just be removed, it seems like a statement? – KamilCuk Sep 01 '21 at 11:37
  • Stackoverflow accepted norm is a single question. Therefore, my post should be understood as a single main question (the first one). The two asides below it won't justify separate posts, and they are added as asides if someone is in the mood to elaborate. And the 3rd question is a question, not a statement: so what do you do without this? I believe the hints about "dereference pointer-to-member" and "r-value reference" put me on the right track for the main question and the first aside. Thanks. – Zohar Levi Sep 01 '21 at 11:42

1 Answers1

5

I'm trying to understand the code below from

Let's say in points:

  • .* is pointer-to-member access operator. See https://en.cppreference.com/w/cpp/language/operator_member_access
  • The code is using internal representation of the priority_queue, it's using the underlying container used by the queue to store data and accessing that data using protected member with the name c.
    • From glibc stl_queue.h:

      class priority_queue
      {
           ...
      protected:
           //  See queue::c for notes on these names.
           _Sequence  c;
           _Compare   comp;
      
    • See this note in queue::c about why it's just named c. And C++98 standard.

  • HackedQueue inherits from priority_queue so it can access it's protected members,
  • &HackedQueue::c is a pointer to member c in class HackedQueue (it is inherited from priority_queue),
  • q.*(&HackedQueue::c); accesses that member c in object q using that pointer-to-member,
  • and then the function returns a reference to that member in the passed object q.

what is &&.

Rvalue reference declarator. See https://en.cppreference.com/w/cpp/language/reference

how do you debug a priority queue, where the basic need is to print its elements?

With a debugger. Anyway, the question is also answered in the linked question How to iterate over a priority_queue? .

KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • 1
    Nitpick: `&HackedQueue::c` is of type `S std::priority_queue::*`, and not of type `S HackedQueue::*`, which is why it's fine to use with something that isn't a `HackedQueue` – Caleth Sep 01 '21 at 12:07