首页 > 解决方案 > 使用 .*& 访问基类成员(访问 priority_queue 容器)

问题描述

我试图从下面的代码中理解

如何迭代priority_queue?

我认为,由于 HackedQueue 是从 priority_queue 私有派生的,因此它可以访问其私有数据。所以,我假设它*&HackedQueue::c返回基类对象的地址,并且它被称为 q。但是,并不完全清楚,甚至更清楚它是如何有效的语法。


提到priority_queue,我想知道是否还有更干净的解决方法。例如,此链接上的 4th c'tor

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

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

似乎提供了一个可以使用的容器,而不是只读输入。我在 Visual Studio 头文件中看不到它,我不清楚什么是&&.


相关,我不理解相反的问题,例如为什么我需要访问私有容器,它不是为此而设计的。那么,您如何调试优先级队列,其中基本需要是打印其元素?


#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;
}

标签: c++

解决方案


我试图从下面的代码中理解

让我们分点说:

  • .*是指向成员的访问运算符。请参阅https://en.cppreference.com/w/cpp/language/operator_member_access
  • 该代码使用 的内部表示priority_queue它使用队列使用的底层容器来存储数据并使用protected名称为 的成员访问该数据c
    • glibc stl_queue.h

      class priority_queue
      {
           ...
      protected:
           //  See queue::c for notes on these names.
           _Sequence  c;
           _Compare   comp;
      
    • 请参阅queue::c 中的此注释,了解为什么它只是命名为c. 和 C++98 标准。

  • HackedQueue继承自priority_queue所以它可以访问它的protected成员,
  • &HackedQueue::c是指向c类中成员的指针HackedQueue(它继承自priority_queue),
  • q.*(&HackedQueue::c);使用指向成员的指针访问c对象q中的该成员,
  • 然后该函数返回对传递对象中该成员的引用q

什么是 &&。

右值引用声明器。请参阅https://en.cppreference.com/w/cpp/language/reference

您如何调试优先级队列,其中基本需要是打印其元素?

带调试器。无论如何,链接的问题How to iterate over a priority_queue?中也回答了这个问题。.


推荐阅读