const_cast:必要之恶

Lobsters Hottest 工具

摘要

本文解释了为什么在C++中有时必须使用const_cast,特别是从std::priority_queue中移动对象时,以及如何安全地使用它。

<p><a href="https://lobste.rs/s/jisg7l/const_cast_necessary_evil">评论</a></p>
查看原文
查看缓存全文

缓存时间: 2026/07/29 17:57

# 必要的恶——为什么乌鸦像写字台? 来源:https://www.elbeno.com/blog/?p=1858 我们不太喜欢`const_cast`。它很丑,甚至可能导致未定义行为。但不幸的是,有时又不得不使用它。即便不考虑那些不尊重`const`属性的C库,C++标准中至少也有一处要求你用到它。如果你有一个`std::priority_queue`,里面存放的是只移对象,你该如何从中取出对象呢?(因为它既不是Roach Motel®,也不是Hotel California……) `pop`函数返回`void`。这毫无帮助。对于其他容器适配器,比如`std::stack`和`std::queue`,`top`/`front`/`back`函数返回的是可变引用。这些容器适配器不需要维护依赖于内部对象状态的不变式。但`std::priority_queue`的`top`函数返回的是`const`引用。`std::priority_queue`*不能*给你一个内部对象的可变引用,因为一旦给了,你就可以修改其中的对象,从而破坏堆的不变式。 所以你能做的唯一一件事,就是使用`const_cast`,暂时且强制地打破这个不变式,然后再恢复它。 ```cpp // top 只能给我们一个 const 引用 const T& obj = q.top(); // 我们必须去除 const 才能把对象移出来, // 这打破了队列的不变式 T exfiltrated_obj = std::move(const_cast<T&>(obj)); // 现在应该立即恢复队列的不变式 q.pop(); ``` 容器适配器在标准中并不受待见:这个问题从C++11起就存在了。我猜,你就捏着鼻子用吧。

相似文章

C++ 标准库在过去十五年间一直在自我撤步,证据公开

Lobsters Hottest

一份详细的目录,列出了从 C++11 到 C++26 期间被正式弃用、非正式不推荐或由于 ABI 约束实际上已损坏但无法修复的 C++ 标准库特性。文章指出,C++ 委员会推出一系列替代品来替换其自身特性的模式始终如一,其中包含一个基准测试,显示 Rust 和 C++ 标准库容器之间的 P99 延迟差异高达 58 倍。

std::function 与 copyable_function 的互转换

Lobsters Hottest

对 C++26 中 std::function 和 std::copyable_function 之间互转换的技术分析,讨论了实现方法和性能权衡,并特别指出 libstdc++ 目前采用了一种较次优的方法。