为什么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,要么是public andDerived的明确基础,忽略cv-限定符。

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

__is_base_of是用于实现std::is_base_of的编译器内在变量。因此,单独使用它不会产生期望的行为。

检查"明确的"public"作为要求的一部分,我们可以检查指向派生对象的指针是否可以隐式地转换为指向基对象的指针。这只是c++类的标准过程。如果类模型和"是",则指针是可转换的。关系,公共继承,而不是来自多个基。

const volatile的添加是为了处理"忽略cv-qualifier"的要求。通过始终添加它们,即使例如_DerivedB const到某些A(非const)_Base,转换也是合法的。按原样比较指针将尝试将B const*转换为A*,并且由于丢弃了cv限定符而失败。

  1. __is_base_of是不够的,因为私有基仍然是基,并且trait检查(用cppreference的话说):

满足derived_from<Derived, Base>概念当且仅当Base是派生类类型或公共且明确的忽略cv限定符.

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

  1. const volatile是需要的,因为性状应该忽略cv-限定符。指向T的指针隐式地转换为指向const volatile T的指针,而指向opposite的指针不为真。

最新更新