c++oding="utf-8" ?>
std::any_cast 直接强转会抛 std::bad_any_cast 异常而非返回 nullptr,易致未捕获崩溃;应优先用指针版本 std::any_cast(&any) 试探,成功返回 t*、失败返回 nullptr,安全可控。

std::any 为什么不能直接用 std::any_cast<t></t> 强转?
因为 std::any_cast<t></t> 在类型不匹配时会抛出 std::bad_any_cast 异常,不是返回 nullptr 或 false——这很容易在未捕获异常时导致程序崩溃。尤其在泛型容器或配置解析等场景里,你根本不确定存进去的是什么类型。
安全做法是先用 std::any_cast<const t></const>(注意是指针重载版本)做试探性转换:
std::any data = 42;
if (auto p = std::any_cast<int>(&data)) {
// 成功:*p 就是 int 值
std::cout
<ul>
<li>必须传入 <code>&data</code>(地址),否则调用的是值版本,失败直接 throw</li>
<li>指针版本返回 <code>T*</code>,空指针表示失败,无异常风险</li>
<li>不要对临时 <code>std::any</code> 取地址(比如 <code>std::any_cast<int>(&std::any{42}))</int></code>),会导致悬垂指针</li>
</ul>
<h3>如何避免 <code>std::any</code> 存储引用或临时对象?</h3>
<p><code>std::any</code> 只能持有可复制/可移动的完整对象,不能安全持有引用、数组、或带 non-trivial 析构的栈对象别名。常见翻车点:</p>
<ul>
<li>
<code>int x = 10; std::any a{x};</code> ✅ 拷贝 x 的值</li>
<li>
<code>std::any a{&x};</code> ❌ 存的是 int*,但你可能误以为存了引用</li>
<li>
<code>std::any a{std::ref(x)};</code> ❌ <code>std::reference_wrapper</code> 虽可存,但取出后仍需手动解包,且生命周期完全靠你保证</li>
</ul>
<p>真正想“间接持有”,应该显式用 <code>std::shared_ptr</code> 或 <code>std::unique_ptr</code> 包一层:</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/gongju/2823" title="C++14"><img
src="https://img.php.cn/upload/manual/001/431/639/6ac8b33c327c4749.png" alt="C++14" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/gongju/2823" title="C++14" class="overflowclass">C++14</a>
<p class="overflowclass">C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。</p>
</div>
<a rel="nofollow" href="/xiazai/gongju/2823" title="C++14" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<pre class="brush:php;toolbar:false;">int x = 10;
auto ptr = std::make_shared<int>(x);
std::any a = ptr; // 安全:所有权明确
if (auto p = std::any_cast<:shared_ptr>>(&a)) {
std::cout
<h3>性能敏感场景下,<code>std::any</code> 的开销在哪?</h3>
<p>每次构造、拷贝、析构 <code>std::any</code> 都涉及动态内存分配(小对象优化 SSO 是否启用取决于实现,但标准不保证)。典型瓶颈:</p>
<ul>
<li>存储小类型(如 <code>int</code>、<code>bool</code>)时,多数 libstdc++/libc++ 会走 SSO,无堆分配</li>
<li>存储大类型(如 <code>std::vector<double>(1000)</double></code>)必然堆分配,且拷贝构造代价高</li>
<li>
<code>std::any_cast</code> 内部需比较 type_info,比普通指针解引用慢一个数量级</li>
</ul>
<p>若频繁读写且类型固定(比如只在 <code>int</code>/<code>double</code>/<code>std::string</code> 间切换),考虑用 <code>std::variant<int double std::string></int></code> 替代:零运行时开销、无异常、编译期类型检查更严。</p>
<h3>和 <code>void*</code> 相比,<code>std::any</code> 真的安全吗?</h3>
<p>安全,但只限于“类型安全”层面:它强制你在取值前做类型校验,不会像 <code>void*</code> 那样允许任意 reinterpret_cast。但它不解决以下问题:</p>
<ul>
<li>线程安全:多个线程同时读写同一个 <code>std::any</code> 实例,必须加锁(<code>std::any</code> 本身非线程安全)</li>
<li>生命周期管理:存进去的对象析构了,但你忘了清空 <code>std::any</code>,后续 cast 会失败或 UB(尤其存的是自定义类型且含裸指针)</li>
<li>调试困难:GDB/Lldb 中 <code>std::any</code> 显示为黑盒,看不到实际类型和值,得靠 <code>std::any.type().name()</code> 辅助判断</li>
</ul>
<p>所以它适合“类型不确定但可控”的场景(如插件系统参数传递、JSON-like 配置解析),不适合高频、低延迟、或需要精细内存控制的底层模块。</p></:shared_ptr></int>C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










