单个模板定义是否可支持使用两种存在子类型关系的不同类型
单模板适配父子类型实现方案
完全可以实现,你可以结合类型约束机制用同一个模板同时适配基类和它的子类。
C11~C17 实现方式
配合std::enable_if和std::is_base_of做模板参数约束即可,示例代码如下:
#include <type_traits> // 基类定义,包含内部类型bar struct Base { using bar = int; }; // 子类定义,继承Base的bar,也可以自行重写bar类型 struct Derived : public Base {}; // 模板定义,仅匹配Base及其子类 template<typename T, typename = std::enable_if_t<std::is_base_of<Base, T>::value>> void foo(T a, typename T::bar b) { // 你的函数逻辑 }
调用时不管传入Base类型还是Derived类型的参数,都可以正常匹配到这个模板,不需要额外写重载。
C++20 简化写法
用concept可以写出更简洁易读的约束,还可以直接把「T必须包含内部类型bar」的要求加进约束里:
#include <concepts> template<typename T> concept ValidType = std::is_base_of_v<Base, T> && requires { typename T::bar; }; template<ValidType T> void foo(T a, T::bar b) { // 你的函数逻辑 }
注意事项
- 如果子类自行重定义了
bar类型,模板会自动优先使用子类定义的bar类型,和你给出的示例写法逻辑一致 - 如果不需要限制「T必须是某一基类的子类」,仅需要T存在
bar类型,C20下直接把concept里的std::is_base_of_v约束去掉即可,C11及以上也可以用void_t实现相同的判断逻辑。
内容的提问来源于stack exchange,提问作者Petar Velev
相关产品推荐
相关产品推荐

