为何可从C++派生类直接访问基类的别名类型?
问题:C++继承中为何能直接访问基类的类型别名?
在开发SI单位制相关代码时,遇到了一个困惑:
首先定义通用基本单位模板:
template<Ratio r, Symbol s> struct base_unit { using ratio = r; using symbol = s; };
接着定义基本量纲模板:
template <typename Dimension> struct base_dimension { using dimension = Dimension; };
具体的基本量纲类型:
struct mass : public base_dimension<mass> {};
最后定义具体单位类型:
struct Kilogram: public mass, public base_unit<Kilo, kg> {};
为约束单位类型,我最初写了这样的concept:
template <typename T> concept Unit = requires { typename T::base_dimension::dimension; typename T::base_unit::ratio; typename T::base_unit::symbol; };
但意外发现,下面这个简化的concept也能通过检查:
template <typename T> concept OtherUnitConcept = requires { typename T::dimension; typename T::ratio; typename T::symbol; };
这两个静态断言都能通过:
static_assert(Unit<Kilogram>); static_assert(OtherUnitConcept<Kilogram>);
我原本以为必须通过T::base_dimension::dimension这种完整路径访问,因为Kilogram本身并没有定义dimension别名,只有base_dimension才有,为什么直接用T::dimension就能找到?
解答
原因很直接:C++的public继承会把基类的公有成员(包括类型别名)带入派生类的作用域,成为派生类可直接访问的成员。
具体到你的代码逻辑:
base_dimension<mass>中的dimension是公有类型别名,mass通过public继承它后,dimension会自动进入mass的作用域;而Kilogram又public继承了mass,所以Kilogram的作用域自然也能直接访问dimension,不需要加base_dimension::前缀。- 同理,
base_unit<Kilo, kg>里的ratio和symbol是公有类型别名,Kilogrampublic继承它之后,这两个别名也直接进入了Kilogram的作用域,所以可以直接用Kilogram::ratio和Kilogram::symbol访问。
你之前的误解是混淆了“基类的嵌套类型”和“继承后可见的成员类型”——public继承的核心作用之一就是把基类的公有成员(包括类型、函数、变量等)“纳入”派生类的作用域,让派生类可以直接使用,无需通过基类名限定。
内容的提问来源于stack exchange,提问作者Alex Vergara
相关产品推荐
相关产品推荐

