在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
,要么是public andDerived
的明确基础,忽略cv-限定符。请注意,当
Base
. 0时,此行为与std::is_base_of
不同是Derived
的私有或受保护的基地。
__is_base_of
是用于实现std::is_base_of
的编译器内在变量。因此,单独使用它不会产生期望的行为。
检查"明确的"public"作为要求的一部分,我们可以检查指向派生对象的指针是否可以隐式地转换为指向基对象的指针。这只是c++类的标准过程。如果类模型和"是",则指针是可转换的。关系,公共继承,而不是来自多个基。
const volatile
的添加是为了处理"忽略cv-qualifier"的要求。通过始终添加它们,即使例如_Derived
从B const
到某些A
(非const)_Base
,转换也是合法的。按原样比较指针将尝试将B const*
转换为A*
,并且由于丢弃了cv限定符而失败。
- __is_base_of是不够的,因为私有基仍然是基,并且trait检查(用cppreference的话说):
满足
derived_from<Derived, Base>
概念当且仅当Base是派生类类型或公共且明确的忽略cv限定符.注意,当Base是派生的私有基或受保护基时,此行为与std::is_base_of不同。
const volatile
是需要的,因为性状应该忽略cv-限定符。指向T
的指针隐式地转换为指向const volatile T
的指针,而指向opposite的指针不为真。