我希望获得标准布局成员变量的偏移量,当为该变量提供一个poiner时.offsetof因为我有一个指针而不是一个名字,所以我无法使用.我当前的代码看起来像这样,我想知道是否有符合标准的方法来摆脱dummy变量.
template<class T>
struct {
ptrdiff_t get_offset( int (T::*mem) )
{
T dummy;
return reinterpret_cast<char*>(&(dummy.*mem))
- reinterpret_cast<char*>(&dummy);
}
};
Run Code Online (Sandbox Code Playgroud)
此函数只能使用int成员变量点进行调用(这是有意的).
我很确定编译器实际上并没有创建dummy变量,但如果我能摆脱它,它仍然很好.我不能使用空指针,因为未定义解除引用null(尽管它可能适用于所有常见的编译器).C++ 03解决方案会很好,或者C++ 11解决方案也很有用(但现在我无法使用).
注意:我已经知道这只是标准兼容T是标准布局类型.
怎么样:
template<class T>
struct {
ptrdiff_t get_offset( int (T::*mem) )
{
union {
int used;
T unused;
} dummy;
return reinterpret_cast<char*>(&(dummy.unused.*mem))
- reinterpret_cast<char*>(&dummy.unused);
}
};
Run Code Online (Sandbox Code Playgroud)
union成员的地址不依赖于正在构造的union成员.已经在C++ 03中工作,但仅适用于POD.
恐怕不存在满足OP要求的符合标准的解决方案。
我可以举几个不合规的。
template<class T>
size_t get_offset( int (T::*mem) )
{
return reinterpret_cast<char*>(&(((T*)nullptr)->*mem))-reinterpret_cast<char*>(nullptr);
}
Run Code Online (Sandbox Code Playgroud)
这很有趣,但以下内容在 VC2010 中有效,利用了offsetof宏。
template<class T>
size_t get_offset( int (T::*mem) )
{
return offsetof(T, *mem);
}
Run Code Online (Sandbox Code Playgroud)