如何用std::any_cast访问std::any内部指针?代码转换问题咨询
关于std::any_cast访问内部指针及代码改造的问题解答
1. 用std::any替代void*的改造方案
你原来的void*版本是存储目标对象的指针,换成std::any后,只需要把指针直接存入std::any(它会保留指针的具体类型信息),再通过std::any_cast的指针重载来获取内部指针即可。改造后的代码如下:
#include <any> struct ReadOperation { public: template <LeafnodeConcept L> static bool visitLeafnode(L *l) { // 把data的指针存入std::any,用std::addressof避免operator&被重载的情况 value = std::addressof(l->data); return false; } template <NodeLike N> static bool previsit(N* n) { return false; } template <class T> static const T GetValue() { // 和原逻辑一致,先拿指针再解引用 return *GetValueRef<T>(); } template<class T> static const T* GetValueRef() { // 核心:传入std::any的地址给any_cast,返回内部存储的指针 return std::any_cast<const T*>(&value); } private: // 替换void*为std::any,默认初始化为空状态 inline static std::any value; };
需要注意的细节:
- 存入std::any的是对象的指针,不是对象本身,和你原来的void*逻辑完全对齐;
std::any_cast<const T*>(&value)这个重载是关键:当你传std::any的地址给any_cast时,它不会返回副本,而是直接返回指向std::any内部存储的指针;如果类型不匹配,这个重载会返回nullptr(不会抛出异常,和传值版本的any_cast行为不同)。
2. 为什么std::any_cast默认返回副本?
std::any_cast的设计是为了兼顾两种使用场景:
- 存储值类型:比如
std::any a = 3.14;,这时候any_cast<double>(a)返回内部值的副本,符合普通值类型的使用习惯,同时避免直接暴露内部存储导致的生命周期风险; - 需要直接访问内部对象:如果你要拿引用或指针,就必须显式使用指针重载版本(传std::any的地址),这相当于给开发者一个明确的提示:你现在要直接操作内部存储的地址,必须自己保证对象的生命周期和类型正确性。
这种设计平衡了易用性和安全性:默认的传值版本简单直观,适合大多数值类型场景;指针版本则提供了灵活的直接访问能力,但把生命周期和类型检查的责任交给开发者,避免误操作。
内容的提问来源于stack exchange,提问作者andir
相关产品推荐
相关产品推荐

