反转指向成员的指针(即获取包含结构的地址)
Invert pointer to member (i.e. get the address of the containing struct)
我有一个结构(Member),它只能用作其他结构(Container)中的数据成员。按照惯例,成员的名称总是m。有没有可靠的方法让成员获得包含结构的地址?
template<typename Struct>
struct Member;
{
const Struct& s = ??;
// this - &Struct::m
};
struct Container
{
Member<Container> m;
};
我希望使用指向成员&Container::m
的指针可能有助于从成员对象本身的地址进行计算?
不,您不能这样做。您可以确定Container
中m
的偏移量,并进行指针运算来猜测Container
的结果地址,但这将是:
- 不可靠的
- 容易出现灾难性错误
- UB(因此可能导致包括时间旅行在内的症状,不,严重!)
如果您禁用了所有优化,它可能会在一些平台上持续运行,但实际上,请不要这样做。
将指向Container
的指针/引用传递到Member<Container>
的构造函数中(添加一个之后),或者进一步重新考虑您的设计。为什么成员需要知道封装它的对象?这几乎总是错误的(尽管有一些可以通过的用例)。
不确定"可靠",这是不应该鼓励的黑客行为,但以下应该给你一个很好的起点:
#include <cassert>
#include <cstddef>
#include <type_traits>
template<typename Struct>
struct Member
{
Struct const* s = (Struct*)&((char*)this)[-(int)offsetof(Struct, m)];
};
struct Container
{
int abc;
int def;
Member<Container> m;
};
int main(int argc, char* argv[])
{
assert(std::is_standard_layout<Container>::value);
Container c;
Container const *p1 = &c;
Container const *p2 = c.m.s;
bool test = p1 == p2;
return 0;
}
我添加了一些成员,以便m有一个实际的非零偏移量进行测试,但它也适用于零偏移量。
相关文章:
- 当映射包含字符串向量作为值时,从值中获取键的有效方法
- 如何在两个列表中比较和获取非包含值
- 如何从 QString 中包含的十六进制值中获取 ASCII 字符?
- 如何获取包含 NULL 字符的外壳代码字符串的长度
- C++ LibcURL IMAP 获取包含主题行的变量是什么?
- C++:获取包含成员子对象的完整对象的地址
- 如何在不包含 Windows.h 的情况下获取 IsDebuggerPresent 的声明
- 如何从文件句柄获取包含目录的句柄
- Qt - 为什么无法使用 QFile 读取文件,其中包含从 FileDialog 获取的目录
- 获取包含C++的捆绑包中文件的路径(CFBundleGetMainBundle)
- 从 std::aligned_union_t 获取指向包含对象的指针
- 无法获取包含C++空格的输入
- 在c++中获取包含特征库的错误
- 无法获取包含文件'excpt.h'的视觉工作室C++以进行安装
- 获取包含共享库的c++应用程序的调用堆栈
- 反转指向成员的指针(即获取包含结构的地址)
- 如何:给定文件描述符,获取包含文件的设备的设备节点
- 获取包含项目中每个文件的所有头文件的列表
- clang在解析AST时获取包含文件
- 获取包含类的类型