从指向成员变量的指针获取对象的地址

Getting object's address from its pointer to member variable

本文关键字:指针 获取 取对象 地址 变量 成员      更新时间:2023-10-16

我正在尝试从指向成员变量的指针获取实际对象的指针。

是的,我知道有offsetof宏,但它需要成员变量的名称,而不是指向成员变量的指针。

实际上实施起来

并不困难,但我不确定它是 100% 标准的一致性代码。

template <class T, class M, M T::*Ptr>
constexpr std::ptrdiff_t offset_to_member()
{
  return static_cast<char*>(static_cast<void*>(&(static_cast<T*>(nullptr)->*Ptr)))
         - static_cast<char*>(nullptr);
}
template <class T, class M, M T::*Ptr>
constexpr T* object_ptr_from_member(M *__ptr)
{
  // reinterpret_cast is not allowed in constexpr function
  return static_cast<T*>(static_cast<void*>(
           static_cast<char*>(static_cast<void*>(__ptr)) - offset_to_member<T, M, Ptr>()));
}

结果 : http://ideone.com/1Z2nIR

Clang++ 和 g++ 都在没有任何警告的情况下编译了代码,但我需要的不仅仅是"它似乎有效"。

代码在 c++11 标准中有效吗?

static_cast<T*>(nullptr)->*Ptr

等效于 根据 [expr.mptr.oper]/3 (*static_cast<T*>(nullptr)).*Ptr,这会触发未定义的行为。
而不是constexpr(正是因为 UB) - [expr.const]/2:

条件表达式e核心常量表达式,除非 e的评估,遵循抽象机器的规则,将 计算以下表达式之一:

  • 具有未定义行为的操作。