C++:未知派生类类型时将std::any转换为基类
如何在未知派生类类型时将std::any转换为基类指针
问题场景
给定基类定义:
struct HCallable { int numArgs; std::vector<std::type_info> argTypes; virtual std::any call(std::vector<std::any> args)=0; };
其派生类实例被存储在std::any中:
class in : public HCallable { public: int numArgs=1; std::any call(std::vector<std::any> args) { std::cout << huff::anyToString(args[0]); std::string result; std::getline(std::cin, result); return result; } }; std::any instance = std::any(new in());
需要将instance转换为HCallable*类型,但无法提前知晓instance实际存储的派生类类型,且要避免显式指定派生类类型。
解决方案
利用std::any_cast<void*>取出通用指针,再通过dynamic_cast转换为基类指针。由于HCallable包含虚函数,dynamic_cast可以安全地将派生类指针转换为基类指针。
代码示例:
// 先检查存储的是否为指针类型,避免触发异常 if (instance.type().is_pointer()) { void* raw_ptr = std::any_cast<void*>(instance); HCallable* func = dynamic_cast<HCallable*>(raw_ptr); if (func != nullptr) { // 转换成功,可正常调用基类虚函数 // 示例:func->call({}); } }
补充说明
instance.type().is_pointer()用于确保std::any中存储的是指针类型,防止std::any_cast<void*>抛出std::bad_any_cast异常。std::any_cast<void*>可以取出任何指针类型的原始指针,无需提前知晓具体派生类类型。dynamic_cast<HCallable*>会校验原始指针是否指向HCallable的派生类实例,成功返回有效指针,失败则返回nullptr。
如果可以控制存储逻辑,更简洁的方式是在存入std::any时直接转换为基类指针:
std::any instance = static_cast<HCallable*>(new in()); // 后续直接转换 HCallable* func = std::any_cast<HCallable*>(instance);
这种方式无需后续的dynamic_cast操作,流程更直接。
内容的提问来源于stack exchange,提问作者Gamaray
相关产品推荐
相关产品推荐

