Skip to content
Why is a raven like a writing desk?

Thoughts both confusing and enlightening.

Why is a raven like a writing desk?

Thoughts both confusing and enlightening.

const_cast: A Necessary Evil

elbeno, 29 July, 2026

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.

C++

Post navigation

Previous post

Related Posts

VS2010 woes: tuples as map keys

20 February, 201530 June, 2015

Another day, another compiler/library bug. If you’re unfortunate enough to still be using Visual Studio 2010, don’t use tuples as map keys. #include #include #include using namespace std; typedef tuple FooT; typedef map MapT; int main(int, char*[]) { MapT m; // put a value in the map { FooT f(nullptr,…

Read More

Exercising Ranges (part 6)

1 July, 20151 July, 2015

(Start at the beginning of the series if you want more context.) Multiplying power series Now we come to something that took considerable thought: how to multiply ranges. Doug McIlroy’s Haskell version of range multiplication is succinct, lazily evaluated and recursive. (f:ft) * gs@(g:gt) = f*g : ft*gs + series(f)*gt…

Read More

C++23’s new function syntax

5 September, 20225 September, 2022

We’ve had a couple of ways to spell functions for a long time: And we’ve had a shortcut for that second one for a while, too: (Aside: notice where [[nodiscard]] is positioned, since C++23’s P2173, to apply to the lambda’s call operator.) All these ways to spell functions look the…

Read More
©2026 Why is a raven like a writing desk? | WordPress Theme by SuperbThemes