You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于libstdc++中std::any小对象访问用const实现的疑问

问题

在查看libstdc的std::any实现时,发现针对小对象通过aligned_storage进行访问的代码使用了const修饰,这令人困惑。请问这样实现的目的是什么?是否与aligned_storage可能存储const对象有关?若如此,C标准中何处有相关依据?

对应的核心代码片段如下:

static _Tp* _S_access(const _Storage& __storage)
{ 
   // The contained object is in __storage._M_buffer
  const void* __addr = &__storage._M_buffer;
  return static_cast<_Tp*>(const_cast<void*>(__addr));
}

回答

1. const修饰参数的核心目的

这个设计是为了复用同一份访问逻辑,同时兼容const和非const的std::any实例:

  • 当调用std::any_cast<const T>(const std::any&)时,传入的内部_Storage是const的,这个函数可以直接处理;
  • 当调用std::any_cast<T>(std::any&)时,非const的_Storage可以隐式转换为const _Storage&,无需额外写一份非const版本的访问函数。

这里的const_cast是安全的:

  • 如果原始std::any是非const的,_Storage本身就是可修改的,const_cast只是去掉了临时的const限定,不会触发未定义行为;
  • 如果原始std::any是const的,std::any_cast只会返回const T*或const T&,外部无法通过const接口修改对象,内部的非const指针不会被用来做非法修改。

2. 和存储const对象无关

std::any不会存储const对象——当你把const T放入std::any时,它实际存储的是T类型的对象(const限定会被剥离),因为std::any的构造函数会对传入参数进行拷贝/移动,拷贝const T得到的是普通的T实例。

3. C++标准的相关依据

  • const_cast的合法场景:C标准[expr.const.cast]章节明确,当原始对象本身是非const的,去掉const限定是合法操作;只有当原始对象是const的,通过const_cast修改才会触发未定义行为。libstdc的实现通过外部std::any_cast的接口区分了const/非const场景,保证了const_cast的安全性。
  • std::any_cast的行为要求:标准规定std::any_cast<const T>(const std::any&)必须返回const引用/指针,std::any_cast<T>(std::any&)返回非const引用/指针,这个实现完全贴合标准的行为定义。

内容的提问来源于stack exchange,提问作者minex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 18:43:25