在派生数据类型上具有查找函数的 C++ 优先级队列

问题描述

按照这个问题:https://stackoverflow.com/a/16749994/1703586 我有一个来自 std::priority_queue 的派生类。我真正需要的是具有 find() 功能的优先级队列。

当我尝试使用 my_priority_queue 时,我收到一大堆我不明白的错误(粘贴在下面)。使用 std::priority_queue,它编译得很好。

请帮助我理解编译器错误解决问题。

更新: 感谢@rafix07,添加构造函数解决了编译问题(暂时)。

但是由于我的值是元组类型,所以我写了一个自定义查找。请参阅我的查找功能。因此,我仍然遇到其他编译问题。

这是我的独立代码


#include <functional>
#include <queue>
#include <vector>
#include <iostream>

template<typename T>
void print_queue(T q) { // NB: pass by value so the print uses a copy
    while(!q.empty()) {
        auto x = q.top();
        auto cost = std::get<0>( x );
        auto s = std::get<2>( x );

        std::cout << "{ cost=" << cost << " | "  << std::get<0>(s) << "," << std::get<1>(s) << "," << std::get<2>(s) << "}";
        q.pop();
    }
    std::cout << '\n';
}


typedef int OcTreeKey ;
typedef bool NodeOccupancyStatus;
typedef std::tuple<OcTreeKey,int,NodeOccupancyStatus > value_tt; //< key,depth,occupancy-enum

typedef std::tuple< float,value_tt,value_tt > dijstas_tuple; // cost to goal,parent of current,current node


template<
    class T,class Container = std::vector<T>,class Compare = std::less<typename Container::value_type>
> class my_priority_queue : public std::priority_queue<T,Container,Compare>
{
public:
    typedef typename
        std::priority_queue<
        T,Compare>::container_type::const_iterator const_iterator;

      const_iterator find(const T&val) const
    {
        auto node0 = std::get<2>(val);
        int node0_depth = std::get<2>(node0);


        auto first = this->c.cbegin();
        auto last = this->c.cend();
        while (first!=last) {
            // if (*first==val) return first;
            auto node1 = std::get<2>(first);
            int node1_depth = std::get<2>(node1);

            if( node0_depth == node1_depth  ) return first;
            ++first;
        }
        return last;
    }
};




int main() {


    // Using lambda to compare elements.
    auto cmp = [](dijstas_tuple left,dijstas_tuple right) { return ( std::get<0>(left) > std::get<0>(right) ); };
    // std::priority_queue<dijstas_tuple,std::vector<dijstas_tuple>,decltype(cmp)> q3(cmp);
    my_priority_queue<dijstas_tuple,decltype(cmp)> q3(cmp);

    auto node_null = std::make_tuple( 2.0,-1,true );
    auto node_tup0 = std::make_tuple( 2.0,14,true );
    auto node_tup1 = std::make_tuple( 12.0,12,true );
    auto node_tup2 = std::make_tuple( 22.0,true );
    auto node_tup3 = std::make_tuple( 51.0,13,true );

    q3.push( std::make_tuple(8.0,node_null,node_tup0 ) );
    q3.push( std::make_tuple(3.0,node_tup2,node_tup1 ) );
    q3.push( std::make_tuple(7.0,node_tup2 ) );
    q3.push( std::make_tuple(10.0,node_tup1,node_tup3 ) );

    q3.find( std::make_tuple(8.0,node_tup0 )  );

    q3.pop();

    print_queue(q3);

}

这是我的编译器错误

custom_priority_queue.cpp: In function ‘int main()’:
custom_priority_queue.cpp:62:87: error: no matching function for call to ‘my_priority_queue<std::tuple<float,std::tuple<int,bool>,bool> >,std::vector<std::tuple<float,bool> > >,main()::<lambda(dijstas_tuple,dijstas_tuple)> >::my_priority_queue(main()::<lambda(dijstas_tuple,dijstas_tuple)>&)’
 eue<dijstas_tuple,decltype(cmp)> q3(cmp);
                                                                     ^
custom_priority_queue.cpp:32:9: note: candidate: my_priority_queue<std::tuple<float,dijstas_tuple)> >::my_priority_queue(const my_priority_queue<std::tuple<float,dijstas_tuple)> >&)
 > class my_priority_queue : public std::priority_queue<T,Compare>
         ^~~~~~~~~~~~~~~~~
custom_priority_queue.cpp:32:9: note:   no kNown conversion for argument 1 from ‘main()::<lambda(dijstas_tuple,dijstas_tuple)>’ to ‘const my_priority_queue<std::tuple<float,dijstas_tuple)> >&’
custom_priority_queue.cpp:32:9: note: candidate: my_priority_queue<std::tuple<float,dijstas_tuple)> >::my_priority_queue(my_priority_queue<std::tuple<float,dijstas_tuple)> >&&)
custom_priority_queue.cpp:32:9: note:   no kNown conversion for argument 1 from ‘main()::<lambda(dijstas_tuple,dijstas_tuple)>’ to ‘my_priority_queue<std::tuple<float,dijstas_tuple)> >&&’

find 后的编译问题

解决方法

您没有为类提供构造函数。

可能是:

my_priority_queue(const Compare& cmp) : 
       std::priority_queue<T,Container,Compare>(cmp) {}

或者你可以通过使用声明来引入优先队列构造函数:

using std::priority_queue<T,Compare>::priority_queue;

从 C++20 开始(其中 lambda 是默认可构造的)

my_priority_queue<dijstas_tuple,std::vector<dijstas_tuple>,decltype(cmp)> q3;

足够了,它会调用基类默认构造函数 priority_queue() : priority_queue(Compare(),Container()) { },它与默认可构造的 lambda 一起工作正常。