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

时间:2014-12-04 11:16:39

标签: c++ pointers

我试图从指向成员变量的指针中获取实际对象的指针。

是的,我知道有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标准中是否有效?

1 个答案:

答案 0 :(得分:2)

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

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

  

条件表达式 e是一个核心常量表达式,除非   根据抽象机器的规则评估e   评估以下表达式之一:

     
      
  • 将导致未定义行为的操作。
  •