C++ 获取对象';从指针到成员变量的s地址
我试图从指向成员变量的指针中获取实际对象的指针 是的,我知道宏有偏移量,但它需要成员变量的名称,而不是指向成员变量的指针 它实际上并不难实现,但我不确定它是否是100%符合标准的代码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
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内置的偏移量。