c++ 为什么可以从派生类访问基类别名类型?

5vf7fwbs  于 2023-03-25  发布在  其他
关注(0)|答案(1)|浏览(113)

在我的发展历程中,今天我发现了一些我不明白为什么会发生的事情。
这应代表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> {};

因此,我想设计一个概念,检查单位内是否存在这些别名,例如,Kilogram:

struct Kilogram: public mass, public base_unit<Kilo, kg> {};

所以我继续,我写了这个概念,以约束未来的实现者:

template <typename T>
concept Unit = requires {  
    typename T::base_dimension::dimension;
    typename T::base_unit::ratio;
    typename T::base_unit::symbol;
};

但是,令我惊讶的是,我可以写这样的代码:

template <typename T>
concept OtherUnitConcept = requires {  
    typename T::dimension;
    typename T::ratio;
    typename T::symbol;
};
static_assert(Unit<Kilogram>);
static_assert(OtherUnitConcept<Kilogram>);

为什么我可以直接请求T的这些别名?这个想法是,我使用这些继承结构作为tag dispatching,我认为我应该总是采取完整的路线,T::base_dimension::dimension,因为T在它的主体定义中没有typename dimension,但base_dimension有一个,我很惊讶能够直接在结构T::dimension中找到dimension
Here's a minimal working example

6xfqseft

6xfqseft1#

TBH,你的问题应该是 * 为什么我可以从派生类访问基类别名类型?*
这是关于限定名查找的事情。根据cppref,
如果查找左手名称时出现类/结构或联合名称,则::右侧的名称在该类的作用域中查找(因此可能会找到该类或其基类的成员的声明),但有以下例外
因此,如果没有找到T::dimensionT::dimension可以查找T::base_dimension::dimension

相关问题