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

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({});
    }
}

补充说明

  1. instance.type().is_pointer()用于确保std::any中存储的是指针类型,防止std::any_cast<void*>抛出std::bad_any_cast异常。
  2. std::any_cast<void*>可以取出任何指针类型的原始指针,无需提前知晓具体派生类类型。
  3. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 20:33:08