为什么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*>;
- 为什么要求
__is_base_of(_Base, _Derived)
不够? const volatile
测试中需要用到什么?
回答
的行为std::derived_from
是根据明确的公共继承指定的
derived_from<Derived, Base>
当且仅当Base
是 的类类型Derived
或 的公共且明确的基类Derived
,忽略 cv 限定符时,才满足
该概念。请注意,此行为与
std::is_base_of
whenBase
是 的私有或受保护基不同Derived
。
__is_base_of
是用于实现std::is_base_of
. 因此,单独使用它不会产生所需的行为。
因此,为了检查需求的“明确公共”部分,我们可以检查指向派生对象的指针是否可以隐式转换为指向基对象的指针。这只是 C++ 类的标准过程。如果类建模“is-a”关系、公共继承而不是来自多个基类,则指针是可转换的。
在const volatile
除了是处理“忽略cv修饰符”的要求。通过始终添加它们,转换是合法的,即使例如_Derived
是B const
some A
(non-const) _Base
。按原样比较指针会尝试转换B const*
为A*
,并且会因丢弃 cv 限定符而失败。
回答
- __is_base_of 是不够的,因为私有基仍然是基,特征检查(用cppreference 的话):
derived_from<Derived, Base>
当且仅当 Base 是 Derived 或 Derived 的公共且明确的基类的类类型时,才满足该概念,忽略 cv-qualifiers。请注意,当 Base 是 Derived 的私有或受保护基时,此行为与 std::is_base_of 不同。
const volatile
是必需的,因为特征应该忽略 cv 限定符。指向的指针T
隐式转换为指向 的指针const volatile T
,而指向相反的指针则不成立。
THE END
二维码