如何实现concept<A,B>检查类型A是否继承自模板B<...>
解决方案
要实现检查类型A是否继承自模板B的任意实例的概念,我们可以通过SFINAE技术检测类型是否能转换为B<...>的引用(支持直接/间接继承,同时兼容A本身就是B实例的情况)。
修改后的完整代码
#include <vector> #include <iostream> #include <type_traits> namespace hid{ template <typename T,template<typename... Ty> typename B> struct is_mytype : std::false_type { }; template <typename... A,template<typename... Ty> typename B> struct is_mytype<B<A...> ,B> : std::true_type { }; // 新增:检查是否继承自B的任意实例的实现 template <typename T, template<typename...> typename B> struct inherits_from_template_impl { // 匹配任意B<Args...>的引用,若T可转换则返回true_type template <typename... Args> static std::true_type test(const B<Args...>&); // 兜底匹配,返回false_type static std::false_type test(...); // 通过decltype获取test调用结果,提取布尔值 static constexpr bool value = decltype(test(std::declval<T>()))::value; }; // 对外暴露的常量 template <typename T, template<typename...> typename B> constexpr bool inherits_from_template = inherits_from_template_impl<T, B>::value; }; template <typename T,template<typename... Ty> typename B> concept Trait_AActuallyBTemplate = hid::is_mytype<T,B>::value; // 修改后的目标概念 template <typename T,template<typename... Ty> typename B> concept Trait_AInheritFromBTemplate = hid::inherits_from_template<T,B>; int main() { static_assert(Trait_AActuallyBTemplate<std::vector<int>,std::vector>,"hehe1"); static_assert(!Trait_AActuallyBTemplate<int,std::vector>,"hehe2"); struct MyVector : public std::vector<int> {}; static_assert(Trait_AInheritFromBTemplate<MyVector,std::vector>,"hehe3"); // 现在断言可正常通过 }
原理说明
inherits_from_template_impl结构体:- 定义两个重载
test函数:第一个接受任意B<Args...>的常量引用,第二个是可变参数的兜底版本。 - 当用
std::declval<T>()调用test时,若T继承自(或本身就是)B的某个实例,编译器会优先匹配第一个重载,返回std::true_type;否则匹配兜底版本,返回std::false_type。
- 定义两个重载
Trait_AInheritFromBTemplate概念:直接使用上述结构体的value常量作为约束条件,完成继承关系检查。
扩展说明
- 支持直接继承和间接继承(比如
MyVector继承std::vector<int>的情况)。 - 兼容
T本身就是B实例的场景(比如std::vector<int>会被正确识别)。
内容的提问来源于stack exchange,提问作者cppBeginner
相关产品推荐
相关产品推荐

