如何在C++17中实现派生类定义枚举供基类模板使用?
C++17实现派生类专属枚举供基类模板使用的方案
需求说明
需要实现以下目标:
- 派生类拥有专属的
units枚举类型,枚举值仅在派生类作用域内可见 - 基类模板能够使用该枚举类型作为数据类型
- 支持如下调用方式:
Derived d = Derived(Derived::meters); d.SomeFunc(Derived::feet);
原尝试代码的问题
最初的CRTP写法无法编译,原因是实例化Base<Derived>时,Derived属于不完整类型,编译器此时无法访问其内部定义的units_type枚举。
C++20可行方案回顾
C++20通过using enum语法可以直接将外部枚举的所有值导入派生类作用域,实现需求:
template<typename ClassName, typename units_type> class Base{ units_type units; public: Base(units_type Units) : units(Units){}; void SomeFunc(units_type Units){}; }; enum class DerivedUnits{ meters, feet }; class Derived : public Base<Derived, DerivedUnits>{ public: using enum DerivedUnits; // C++20特性 using Base::Base; };
C++17等效实现
由于C17不支持using enum,我们可以通过手动逐个导入枚举值的方式替代,其余逻辑与C20方案一致:
template<typename ClassName, typename units_type> class Base{ units_type units; public: Base(units_type Units) : units(Units){}; void SomeFunc(units_type Units){}; }; enum class DerivedUnits{ meters, feet }; class Derived : public Base<Derived, DerivedUnits>{ public: // 手动导入每个枚举值到Derived作用域 using DerivedUnits::meters; using DerivedUnits::feet; using Base::Base; };
方案说明
- 保持枚举
DerivedUnits的外部定义,确保基类模板可以在实例化时获取完整的类型信息 - 在
Derived类中通过using DerivedUnits::xxx逐个将枚举值导入自身作用域,实现Derived::meters的调用方式 - 继承基类时传递
Derived和DerivedUnits作为模板参数,保证基类使用正确的枚举类型
这样既满足了C++17的环境要求,也完全实现了预期的调用方式和功能。
内容的提问来源于stack exchange,提问作者lequinne
相关产品推荐
相关产品推荐

