0

I would like to inherit from STL priority queue to have some additional functionality such as: allowing removal. But I am struggling to make this work when I use custom comparators. MWE:

#include <queue>

template<typename T, class Container=std::vector<T>, class Compare=std::less<typename Container::value_type>> 
class custom_priority_queue : public std::priority_queue<T, Container, Compare>
{
    public:
    // My additional functions here.
};

int main()
{
    auto pq_comp = [](const int& a, const int& b) { return a <= b; };
    std::priority_queue<int, std::vector<int>, decltype(pq_comp)> pq(pq_comp); // works
    custom_priority_queue<int> pq_custom; // works
    custom_priority_queue<int, std::vector<int>, decltype(pq_comp)> pq_custom2(pq_comp); // Error
    return 0;
}

The error is:

main.cpp: In function ‘int main()’:
main.cpp:15:87: error: no matching function for call to ‘custom_priority_queue, main():: >::custom_priority_queue(main()::&)’
   15 |     custom_priority_queue<int, std::vector<int>, decltype(pq_comp)> pq_custom2(pq_comp); // Error
      |                                                                                       ^
main.cpp:4:7: note: candidate: ‘custom_priority_queue, main():: >::custom_priority_queue(const custom_priority_queue, main():: >&)’
    4 | class custom_priority_queue : public std::priority_queue<T, Container, Compare>
      |       ^~~~~~~~~~~~~~~~~~~~~
main.cpp:4:7: note:   no known conversion for argument 1 from ‘main()::’ to ‘const custom_priority_queue, main():: >&’
main.cpp:4:7: note: candidate: ‘custom_priority_queue, main():: >::custom_priority_queue(custom_priority_queue, main():: >&&)’
main.cpp:4:7: note:   no known conversion for argument 1 from ‘main()::’ to ‘custom_priority_queue, main():: >&&’
4
  • your class has no constructor taking a comparator. That error is somewhat unrelated to inheriting from a std container, which perhaps wasnt a good idea to begin with. Consider that not everything has to be a member. Why don't you write a free function remove if thats what you want to "add" to priority_queue ? Commented Oct 17, 2022 at 12:12
  • 1
    standard library containers are not intended to be inherited from Commented Oct 17, 2022 at 12:13
  • 1
    @463035818_is_not_a_number The class allows only protected access to the underlying container and that is required to implement this. Commented Oct 17, 2022 at 12:15
  • @NeilButterworth std::priority_queue specifically has protected member access to the underlying container. It seems to be designed with this use case in mind. Commented Oct 17, 2022 at 12:16

1 Answer 1

1

Constructors are not automatically inherited, so your class probably lacks any constructor, except the implicitly-declared ones.

You can explicitly inherit all constructors of the base class:

template<typename T, class Container=std::vector<T>, class Compare=std::less<typename Container::value_type>> 
class custom_priority_queue : public std::priority_queue<T, Container, Compare>
{
    // inherit constructors
    using priority_queue::priority_queue;

    public:
    // My additional functions here.
};
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for prompt response. I had to make a small change as using std::priority_queue<T, Container, Compare>::priority_queue; and then it works.
@Ahmed Yes, sorry. I mixed up the two possible alternative spellings. See my edit for the simpler one that should also work here.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.