c++ - constexpr 检查两个层次相关类型之间指针的 static_cast 是否更改指针值
问题描述
对于我正在实现的一些专门的类似分配器的东西,我想要求所有将要存储的对象共享一个公共基类作为它们的第一个子对象。这使我可以将公共基类的单个指针作为对象开始的指示符,并使用 重新获得对原始对象的访问权限static_cast
,假设我有某种方法可以知道原始对象的类型。
具体来说,我希望以下等式始终适用于任何指向ptr
type的指针,假设andBase
之间没有虚拟继承。Derived
Base
reinterpret_cast<char *>(static_cast<Derived*>(ptr)) == reinterpret_cast<char *>(ptr)
我假设这个等式要么适用于给定类层次结构的所有有效指针,要么不适用于给定类层次结构的任何有效指针。那是对的吗?
因此,该检查应该可以在编译时进行,甚至不知道ptr
. 那么有没有一种constexpr
方法可以检查static_cast
两个相关类型之间的 a 是否改变了指针值?上面的相等性似乎是不可接受的,因为我发现没有 constexpr 方法来创建测试指针。
解决方案
您要问的是指针互转换性。有一个相关的特性std::is_pointer_interconvertible_base_of
在 gcc 和 clang 中还没有实现。另见论文和问题。指针可互换类型具有相同的地址,并且它们的指针可以在reinterpret_cast
.
我假设这个等式要么适用于给定类层次结构的所有有效指针,要么不适用于给定类层次结构的任何有效指针。那是对的吗?
正如您已经指出的,虚拟继承会阻止这一点,但标准布局标准的失败也是如此。如果Derived
有多个基类,并且Base
不是第一个,则失败。
该问题未能激发具有相同地址的要求。如果这不是必需的,那么只要继承关系不是虚拟的、明确的和公共的,从tostatic_cast
向上转换和从to向下转换就可以工作。Derived
Base
Base
Derived
推荐阅读
- python - 如何为多个连接的表/模型创建棉花糖模式
- javascript - 引导 vue 分页无法正常工作
- c# - C#如何检查列表中的数组
- sql - 函数正在产生编译错误
- python - .isin() 比 .query() 快吗
- javascript - Highcharts Angular - 如何在工具提示中显示组大小
- flutter - 颤振:PageView.builder onPage 属性 - 我可以更改以便在全页面滑动而不是 0.50 时触发索引
- amazon-web-services - 如何使用 xtrabackup 将远程 AWS RDS mariaDB 服务器备份到本地目录
- python - selenium-python 点击坐标:“+ 不支持的操作数类型”
- c - 从 uint8_t 到十六进制字符串数组?