从成员中查找结构基地址的标准方法 [英] Standard way to find base address of struct from a member
问题描述
struct Data {
int a;
std::string b;
float c;
};
std::string* allocateDataAndGetString() {
Data* dataPtr(someAllocator.allocate<Data>());
return &dataPtr.b;
}
Data* getBaseDataPtrFromString(std::string* mStringMember) {
// ???
}
int main() {
std::string* stringPtr(allocateDataAndGetString());
Data* dataPtr(getBaseDataPtrFromString
}
我在堆上分配了一个Data
实例,并有一个指向其std::string b;
成员的指针.如何以标准方式考虑到偏移量和填充来获取字符串所属的Data
实例的基址?
I have a Data
instance allocated on the heap, and a pointer to its std::string b;
member. How do I get the base address of the Data
instance the string is a member of, taking into account offsets and padding, in a standard way?
我尝试从std::string*
指针中减去sizeof(int)
和std::offsetof(Data, std::string)
,但是我无法使它起作用.
I've tried subtracting sizeof(int)
and std::offsetof(Data, std::string)
from the std::string*
pointer, but I couldn't get it to work.
推荐答案
使用<cstddef>
中的offsetof
,但请注意,它仅在标准布局类型上定义(
Use offsetof
from <cstddef>
, but beware it is only defined on standard-layout types (Live at Coliru):
Data* getBaseDataPtrFromString(std::string* mStringMember) {
static_assert(std::is_standard_layout<Data>::value,
"offsetof() only works on standard-layout types.");
return reinterpret_cast<Data*>(
reinterpret_cast<char*>(mStringMember) - offsetof(Data, b)
);
}
offsetof
在C ++ 11 18.2/4中有详细说明:
offsetof
is detailed in C++11 18.2/4:
宏
offsetof
( type , member-designator )在此国际标准中接受一组受限制的类型参数.如果 type 不是标准布局类(第9条),则结果是不确定的. 195 表达式offsetof
( type , member-designator )从不依赖于类型(14.6.2.2),并且仅当 type 是依赖于值时,才依赖于值(14.6.2.3).将offsetof
宏应用于静态数据成员或函数成员的字段的结果是不确定的.offsetof
宏调用的任何操作都不会抛出异常,并且noexcept(offsetof(type, member-designator))
应该是true
.
The macro
offsetof
(type, member-designator) accepts a restricted set of type arguments in this International Standard. If type is not a standard-layout class (Clause 9), the results are undefined.195 The expressionoffsetof
(type, member-designator) is never type-dependent (14.6.2.2) and it is value-dependent (14.6.2.3) if and only if type is dependent. The result of applying theoffsetof
macro to a field that is a static data member or a function member is undefined. No operation invoked by theoffsetof
macro shall throw an exception andnoexcept(offsetof(type, member-designator))
shall betrue
.
和C99(N1256)7.17/3:
and C99 (N1256) 7.17/3:
宏是
NULL
扩展为实现定义的空指针常量;和
which expands to an implementation-defined null pointer constant; and
offsetof(type, member-designator)
扩展为一个整数常量表达式,其类型为size_t
,其值是从...的开头到结构成员(由 member-designator 指定)的偏移量(以字节为单位).其结构(由 type 指定).类型和成员指示符应为给定的
which expands to an integer constant expression that has type size_t
, the value of which is the offset in bytes, to the structure member (designated by member-designator), from the beginning of its structure (designated by type). The type and member designator shall be such that given
static type t;
然后,表达式&(t.
member-designator )
得出一个地址常数. (如果指定的成员是位字段,则行为是不确定的.)
then the expression &(t.
member-designator)
evaluates to an address constant. (If the specified member is a bit-field, the behavior is undefined.)
C ++标准中的此国际标准中的类型参数的限制集"可以吸引您注意以下事实,即offsetof
比C标准的情况更具限制性.
The "restricted set of type arguments in this International Standard" in the C++ standard is there to draw your attention to the fact that offsetof
is more restrictive than is the case for the C standard.
这篇关于从成员中查找结构基地址的标准方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!