c++ - 为什么 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”关系、公共继承而不是来自多个基类,则指针是可转换的。
添加是为了处理“忽略 cv-qualifiers”的const volatile
要求。通过始终添加它们,即使转换为_Derived
some B const
( A
non-const)也是合法的_Base
。按原样比较指针会尝试转换B const*
为A*
,并且会由于丢弃的 cv 限定符而失败。
推荐阅读
- laravel - 您的要求无法解决为一组可安装的软件包。Laravel 5.6?
- asp.net-mvc - OAuth 2.0 和 Open ID Connect:无需专用链接/按钮即可集成多个 Open ID Connect 端点的标准方式
- python-3.x - MATLAB chi2ogf(x) 的 Python 等效项
- angular - Angular 5 / 6. 我在哪里放置我的登录页面?
- .net - REST api 在已安装的服务器上不起作用
- vba - 如何使我的代码在所有工作表中工作,而不仅仅是在当前活动工作表中?
- php - 当我在 laravel 的刀片中使用 foreach 时,last() 或 end() 不起作用
- php - PrestaShop ObjectModelCore::hydrateCollection()
- javascript - Javascript将整数应用于其他值
- google-bigquery - BigQuery 错误:无法返回相对于 Unix 纪元的 6328502092800000000 微秒的无效时间戳值