如何静态检查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
相关产品推荐
相关产品推荐

