简体   繁体   中英

Why doesn't std::priority_queue have a clear() member function

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:

  1. It requires you to repeat the type - this does not continue to work under maintenance. As @chris pointed out below, you can simplify this if you're using the default constructor, but if you have a custom comparator, this may not be possible.
  2. std::priority_queue cannot be used in a templated function that expects a clear() member function.
  3. It is generally undesirable that it does not meet the common interface provided by the other containers. In particular, everything from 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:

  1. For internal containers that do not provide clear() , as long as nobody attempts to invoke std::priority_queue::clear() , the code will continue to compile.
  2. It may still be possible with SFINAE to provide the new interface (the clear member) by calling 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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM