首页 > 解决方案 > 为什么 std::derived_from 概念是通过添加 cv 限定符的附加可转换性测试来实现的?

问题描述

在 GCC C++20 概念库中,它有

template<typename _Derived, typename _Base>
    concept derived_from = __is_base_of(_Base, _Derived)
    && is_convertible_v<const volatile _Derived*, const volatile _Base*>;
  1. 为什么要求__is_base_of(_Base, _Derived)还不够?
  2. 测试中需要用到const volatile什么?

标签: c++c++20libstdc++c++-concepts

解决方案


的行为std::derived_from是根据明确的公共继承指定的

derived_from<Derived, Base>当且仅当 Base类类型是Derived或者是 的公共且明确的基类时,该概念才满足Derived,忽略 cv 限定符。

请注意,此行为与std::is_base_ofwhenBase 是 的私有或受保护基时不同Derived

__is_base_of是用于实现的编译器内在函数std::is_base_of。因此,单独使用它不会产生所需的行为。

因此,为了检查需求的“明确的公共”部分,我们可以检查指向派生对象的指针是否可以隐式转换为指向基础对象的指针。这只是 C++ 类的标准过程。如果类建模“is-a”关系、公共继承而不是来自多个基类,则指针是可转换的。

添加是为了处理“忽略 cv-qualifiers”的const volatile要求。通过始终添加它们,即使转换为_Derivedsome B const( Anon-const)也是合法的_Base。按原样比较指针会尝试转换B const*A*,并且会由于丢弃的 cv 限定符而失败。


推荐阅读