为什么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测试中需要用到什么?

回答

的行为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”关系、公共继承而不是来自多个基类,则指针是可转换的。

const volatile除了是处理“忽略cv修饰符”的要求。通过始终添加它们,转换是合法的,即使例如_DerivedB constsome A(non-const) _Base。按原样比较指针会尝试转换B const*A*,并且会因丢弃 cv 限定符而失败。


回答

  1. __is_base_of 是不够的,因为私有基仍然是基,特征检查(用cppreference 的话):

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

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

  1. const volatile是必需的,因为特征应该忽略 cv 限定符。指向的指针T隐式转换为指向 的指针const volatile T,而指向相反的指针则不成立。

以上是为什么std::derived_from概念是通过添加cv限定符的附加可转换性测试来实现的?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>