We don’t like const_cast much. It’s ugly, and can even lead to undefined behaviour. But unfortunately sometimes it’s needed. Even aside from interacting with C libraries which don’t respect const, there is at least one place in the C++ standard that requires you to use it.
If you have a std::priority_queue of move-only objects, how do you get objects out of it? (Because It’s not a Roach Motel®, neither is it Hotel California…)
The pop function returns void. No help there.
With other container adapters like std::stack and std::queue, the top/front/back functions return mutable references. Those container adapters don’t have invariants to uphold that depend on the state of the contained objects.
But the top function on std::priority_queue returns a reference-to-const. std::priority_queue can’t give you a mutable reference to anything inside it, because if it did that, you could alter objects inside it, and that means you could break the heap invariant.
So the only thing you can do is use const_cast, temporarily and forcibly break the invariant, and then restore it.
// top can only give us a reference to const
const T& obj = q.top();
// we must cast away const to move the object out,
// breaking the queue's invariant
T exfiltrated_obj = std::move(const_cast<T&>(obj));
// now we should immediately restore the queue invariant
q.pop();
Container adapters don’t get much love in the standard: this has been broken since C++11. Hold your nose, I guess.
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.