为什么 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 的行为是根据 unambiguous public inheritance

指定的

概念 derived_from<Derived,Base> 满足当且仅当 Base 是一个类类型,要么是 Derived 要么是公共和 Derived 的明确基数,忽略 cv 限定符。

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

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

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

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

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

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

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

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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...