I was doing some hacking today and found out that std::priority_queue does not have a clear()
member function. Are there any technical reasons as to why the standards committee may have left this out?
To be clear, I am aware that it is easy to work around this via assignment:
oldPQ = std::priority_queue<int>{};
This solution is less desirable because:
std::priority_queue
cannot be used in a templated function that expects a clear()
member function.std::forward_list
to std::unordered_map
to std::string
has clear()
. The only other exceptions I note are std::array, for which the semantics would not make sense, and std::stack
and std::queue
, for which the semantics are more questionable when std::deque
works without any extra effort.One item that looks like an issue, but in practice needn't be:
Because the internal container used for std::priority_queue
is templated and may not have a clear()
member function of its own, this creates an interesting problem, in particular it raises the question of backward compatibility. This is a non-issue because:
clear()
, as long as nobody attempts to invoke std::priority_queue::clear()
, the code will continue to compile.clear()
on the internal container when it's available and by repeatedly popping if it is not.It is my opinion that this is a defect in the C++ standard. Assuming a technical discussion does not provide a strong case for why this method is omitted, I intend to pursue the creation of a standards proposal.
Edit:
Seems this is being handled in-committee (note the last post): https://groups.google.com/a/isocpp.org/forum/?fromgroups#!searchin/std-discussion/clear/std-discussion/_mYobAFBOrM/ty-2347w1T4J
http://wg21.cmeerw.net/lwg/issue2194
priority_queue doesn't have a clear method. It may be that this is for interface simplicity, or because it there may be situations in which elements must be destroyed in priority-order, making a generic clear function unsafe.
The priority queue only offers access to the largest element, while the set gives you a complete ordering of all elements. This weaker interface means that implementations may be more efficient (e.g. you can store the actual queue data in a vector , which may have better performance on account of its memory locality).
std::priority_queue A priority queue is a container adaptor that provides constant time lookup of the largest (by default) element, at the expense of logarithmic insertion and extraction.
Remove Item from a C++ QueueThe pop() method is used to remove an item from a queue in C++. The pop() function removes the item at the first position in the queues, because queues use the first-in, first-out data structure.
The specification of container adaptors is known to be overly pedantic: since the "abstract" spec of the corresponding data structure (from some book on abstract algorithms and data structures) does not include operation clear for canonical priority queues or stacks, it is not provided in the adaptor. This indeed often makes it quite inconvenient to use these adaptors in practice.
The good news though is that the inner container member is declared inside the adaptor as a protected member of the adapter, named c
. This is probably done specifically for you to be able to easily implement your own version of the adaptor: by inheriting from the standard adaptor and adding whatever member functions you want to add, including clear
.
As for comparing these adaptors' interfaces with standard container interfaces... I don't think it is a valid comparison. These adaptors have never been intended to be compatible with containers in terms of interface. Quite the opposite, the purpose of these adaptors was largely to restrict the public interface of the data structure and force it into the narrow bounds of what is allowed by its canonical abstract definition.
For example, you are not allowed to iterate over the canonical stack. Stack, by definition, is not "iterable". The fact that stack adaptor disables iteration interface is a good thing. But the absence of clear
certainly feels too pedantic, since it has a great practical value without looking like a big violation of the canonical interface.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With