C++ 为什么std::派生自概念,并通过添加cv限定符的附加可兑换性测试来实现?

C++ 为什么std::派生自概念,并通过添加cv限定符的附加可兑换性测试来实现?,c++,c++20,libstdc++,c++-concepts,C++,C++20,Libstdc++,C++ Concepts,在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*>; 模板 从中派生的概念=\uuuu是(\u base,\u派生的)的\u

在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*>;
模板
从中派生的概念=\uuuu是(\u base,\u派生的)的\u base
&&是可兑换的;
  • 为什么仅仅要求
    \u\u是(\u base,\u Derived)
    还不够
  • 测试中需要使用
    const volatile
    什么
  • __is_base_of是不够的,因为私有基仍然是基,并且特征检查(用词表示):
  • 当且仅当Base是派生的类类型或公共且明确的派生的基,忽略cv限定符时,才满足
    派生的概念

    请注意,当base是派生的私有或受保护的base时,此行为与std::is_base_不同

  • const volatile
    是必需的,因为traits应该忽略cv限定符。指向
    T
    的指针隐式转换为指向
    const volatile T
    的指针,而指向相反的指针则不正确

  • std::derived_from
    的行为是根据

    当且仅当
    Base
    派生的
    或公共和
    派生的
    的明确基,忽略cv限定符

    注意,当
    base
    派生的
    的私有或受保护的基

    \uuuuu是
    的基础,是用于实现
    std::is\u-base\u的编译器内部。因此,单独使用它不会产生期望的行为

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

    添加的
    常量volatile
    用于处理“忽略cv限定符”的要求。通过始终添加它们,即使从
    \u派生的
    B常量
    到一些
    A
    (非常量)
    \u基
    ,转换也是合法的。按原样比较指针将尝试将
    B const*
    转换为
    A*
    ,并且由于丢弃了cv限定符而失败