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

如何静态检查shared_ptr指向的类型是否为ABC派生类?

解决模板容器适配智能指针的约束问题

问题核心是你的extendsABC概念只检查直接类型是否继承自ABC,但std::shared_ptr<Derived>本身并不是ABC的派生类,而是包装指针的模板类,因此约束不通过。我们需要修改概念,让它能识别智能指针指向的类型是否继承自ABC。

修改方案

1. 编写类型萃取工具

先实现一个辅助 trait,用来提取指针/智能指针指向的底层类型:

#include <list>
#include <memory>
#include <type_traits>

class ABC {
  virtual void foo() = 0;
};

// 基础模板:处理非指针/智能指针类型
template<typename T>
struct underlying_type {
    using type = T;
};

// 特化:处理原始指针
template<typename T>
struct underlying_type<T*> {
    using type = T;
};

// 特化:处理std::shared_ptr
template<typename T>
struct underlying_type<std::shared_ptr<T>> {
    using type = T;
};

// 特化:处理std::unique_ptr
template<typename T>
struct underlying_type<std::unique_ptr<T>> {
    using type = T;
};

// 简化类型别名
template<typename T>
using underlying_type_t = typename underlying_type<T>::type;

2. 更新extendsABC概念

修改概念,判断底层类型是否继承自ABC:

template <typename T>
concept extendsABC = std::is_base_of_v<ABC, underlying_type_t<T>>;

3. 调整容器类和派生类

现在容器类可以接受原始类型或智能指针,派生类的静态成员也能正常使用:

template <extendsABC T>
struct extendsABCStore {
  std::list<T> m_data;
};

struct Derived;

struct Derived : public ABC {
  void foo() override{};
  static extendsABCStore<std::shared_ptr<Derived>> instances;
};

// 必须定义静态成员,否则链接阶段报错
extendsABCStore<std::shared_ptr<Derived>> Derived::instances;

说明

  • 类型萃取工具underlying_type会根据传入的类型,提取出真正需要检查的底层类型:比如std::shared_ptr<Derived>会被提取为Derived。
  • 更新后的extendsABC概念会检查这个底层类型是否继承自ABC,这样不管是传Derived还是std::shared_ptr<Derived>,都能满足约束。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 13:05:02