const_cast: A Necessary Evil

Lobsters Hottest Tools

Summary

The article explains why const_cast is sometimes necessary in C++, specifically for moving objects out of a std::priority_queue, and how to do it safely.

<p><a href="https://lobste.rs/s/jisg7l/const_cast_necessary_evil">Comments</a></p>
Original Article
View Cached Full Text

Cached at: 07/29/26, 05:57 PM

# A Necessary Evil – Why is a raven like a writing desk? Source: [https://www.elbeno.com/blog/?p=1858](https://www.elbeno.com/blog/?p=1858) 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\.

Similar Articles

The C++ Standard Library Has Been Walking Itself Back for Fifteen Years, and the Receipts Are Public

Lobsters Hottest

A detailed catalogue of C++ standard library features that have been formally deprecated, informally discouraged, or are effectively broken but cannot be fixed due to ABI constraints, spanning from C++11 to C++26. The article argues a consistent pattern of the C++ committee shipping replacements for its own features, including a benchmark showing 58x P99 latency difference between Rust and C++ standard library containers.

Interconverting std::function with copyable_function

Lobsters Hottest

Technical analysis of the interconversion between std::function and std::copyable_function in C++26, discussing implementation approaches and performance trade-offs, with specific note that libstdc++ currently uses a less optimal approach.