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

如何让std::shared_ptr<Derived>自动转换为std::shared_ptr<Base>类型参数?

问题原因

当传入std::shared_ptr<Derived<std::string>>时,编译器尝试推导原print函数的模板参数Vty,需要让Base<Vty>与Derived<std::string>完全匹配——显然这不可能,因为Derived是Base的派生类而非同一个类,所以模板推导直接失败,不会尝试执行std::shared_ptr<Derived<T>>到std::shared_ptr<Base<T>>的隐式转换。

解决方法

不用修改原print函数的核心形式,只需添加重载来处理派生类智能指针的情况,让重载函数负责转换后调用原函数:

情况1:适配固定模板类Derived

如果Derived是固定的模板类(如template<typename T> class Derived : public Base<T>),可以添加针对性重载:

// 原print函数,保持不变
template<typename Vty>
void print(const std::shared_ptr<Base<Vty>>& ptr) {
    // 原有实现逻辑
}

// 新增重载,处理Derived<T>类型的shared_ptr
template<typename Vty>
void print(const std::shared_ptr<Derived<Vty>>& ptr) {
    print(std::static_pointer_cast<Base<Vty>>(ptr));
}

情况2:适配任意Base的派生类模板

如果需要支持所有继承自Base<T>的派生类模板,可用模板模板参数实现通用重载:

// 原print函数,保持不变
template<typename Vty>
void print(const std::shared_ptr<Base<Vty>>& ptr) {
    // 原有实现逻辑
}

// 通用重载,适配任意继承Base<Vty>的派生类模板
template<typename Vty, template<typename> class Derived>
void print(const std::shared_ptr<Derived<Vty>>& ptr) {
    static_assert(std::is_base_of_v<Base<Vty>, Derived<Vty>>, "Derived must inherit from Base");
    print(std::static_pointer_cast<Base<Vty>>(ptr));
}

情况3:适配任意Base的派生类(含非模板类)

如果还要兼容非模板的派生类,可利用类型推导判断继承关系实现更通用的重载:

#include <type_traits>
#include <memory>

// 原print函数,保持不变
template<typename Vty>
void print(const std::shared_ptr<Base<Vty>>& ptr) {
    // 原有实现逻辑
}

// 通用重载,适配所有Base<Vty>的派生类
template<typename Derived>
auto print(const std::shared_ptr<Derived>& ptr) -> std::enable_if_t<
    std::is_base_of_v<Base<typename Derived::value_type>, Derived>,
    void
> {
    using Vty = typename Derived::value_type;
    print(std::static_pointer_cast<Base<Vty>>(ptr));
}

注:这里假设派生类Derived定义了value_type类型别名(模板类Derived<T>可默认添加using value_type = T;)。

以上方法均保留了原print函数的形式,通过新增重载实现自动转换,无需修改原函数的参数与核心逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 03:13:32