C++ 获取对象';从指针到成员变量的s地址

C++ 获取对象';从指针到成员变量的s地址,c++,pointers,C++,Pointers,我试图从指向成员变量的指针中获取实际对象的指针 是的,我知道宏有偏移量,但它需要成员变量的名称,而不是指向成员变量的指针 它实际上并不难实现,但我不确定它是否是100%符合标准的代码 template <class T, class M, M T::*Ptr> constexpr std::ptrdiff_t offset_to_member() { return static_cast<char*>(static_cast<void*>(&(st

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

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

它实际上并不难实现,但我不确定它是否是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>()));
}
模板
constexpr std::ptrdiff_t offset_to_member()
{
返回static_cast(static_cast(&(static_cast(nullptr)->*Ptr)))
-静态_-cast(nullptr);
}
模板
constexpr T*对象\u ptr\u来自\u成员(M*\u ptr)
{
//constexpr函数中不允许重新解释\u cast
返回静态\u转换(静态\u转换(
静态转换(静态转换(uu ptr))-偏移到成员();
}
结果:

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

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

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

条件表达式
e
是核心常量表达式,除非 按照抽象机器的规则,对
e
进行评估 计算以下表达式之一:

  • 具有未定义行为的操作

这怎么不需要成员的“名称”呢?没有符合标准的方法来做到这一点。编译器不会警告您,因为您正在告诉他们关闭并编译(强制转换)。@JoachimPileborg您可以使用
offsetof
实现
对象\u ptr\u from_member
?这是给定的条件。为什么我会问这样一个问题,如果我可以改变我想要的一切?我不认为第一个语句实际上取消了nullptr的引用。如果它触发UB,那么除了编译器扩展之外,没有100%符合标准的
offsetof
实现,对吗?@kukyakya:是的,
offsetof
不能在符合标准的代码中实现。但是不用担心,这个实现可以自由地执行任何必要的魔法来完成任务。@kukyakya GCC使用一个内在的,即
\uuuu内置的
偏移量。