我试图从指向成员变量的指针中获取实际对象的指针。
是的,我知道有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>()));
}
Clang ++和g ++都在没有任何警告的情况下编译了代码,但我需要的不仅仅是“它似乎正常工作”。
代码在c ++ 11标准中是否有效?
答案 0 :(得分:2)
static_cast<T*>(nullptr)->*Ptr
根据[expr.mptr.oper] / 3等同于(*static_cast<T*>(nullptr)).*Ptr
,它会触发未定义的行为。
而不是constexpr
(正是因为UB) - [expr.const] / 2:
条件表达式
e
是一个核心常量表达式,除非 根据抽象机器的规则评估e
评估以下表达式之一:
- 将导致未定义行为的操作。