考虑以下包含一些环境值的结构:
struct environment_values {
uint16_t humidity;
uint16_t temperature;
uint16_t charging;
};
我想为这些具有幻像类型*的值添加一些附加信息,并同时使它们的类型不同:
template <typename T, typename P>
struct Tagged {
T value;
};
// Actual implementation will contain some more features
struct Celsius{};
struct Power{};
struct Percent{};
struct Environment {
Tagged<uint16_t,Percent> humidity;
Tagged<uint16_t,Celsius> temperature;
Tagged<uint16_t,Power> charging;
};
Environment
的内存布局和environment_values
一样吗?这是否也适用于混合类型布局,例如:
struct foo {
uint16_t value1;
uint8_t value2;
uint64_t value3;
}
struct Foo {
Tagged<uint16_t, Foo> Value1;
Tagged<uint8_t , Bar> Value2;
Tagged<uint64_t, Quux> Value3;
}
到目前为止,我尝试过的所有类型都有以下断言:
template <typename T, typename P = int>
constexpr void check() {
static_assert(alignof(T) == alignof(Tagged<T,P>), "alignment differs");
static_assert(sizeof(T) == sizeof(Tagged<T,P>), "size differs");
}
// check<uint16_t>(), check<uint32_t>(), check<char>() …
由于标记和未标记变体的大小也相同,我猜答案应该是肯定的,但我想有一些确定性。
* 我不知道在 C++ 中如何调用这些标记值。 “强类型类型定义”?我取自 Haskell 的名字。
最佳答案
标准在 [basic.align]/1 中提及:
Object types have alignment requirements (3.9.1, 3.9.2) which place restrictions on the addresses at which an object of that type may be allocated. An alignment is an implementation-defined integer value representing the number of bytes between successive addresses at which a given object can be allocated. An object type imposes an alignment requirement on every object of that type; stricter alignment can be requested using the alignment specifier (7.6.2).
此外,[basic.compound]/3 ,提及:
The value representation of pointer types is implementation-defined. Pointers to layout-compatible types shall have the same value representation and alignment requirements (6.11). [Note: Pointers to over-aligned types (6.11) have no special representation, but their range of valid values is restricted by the extended alignment requirement].
因此,可以保证布局兼容的类型具有相同的对齐方式。
struct { T m; }
和 T
布局不兼容。
正如所指出的 here ,为了使两个元素布局兼容,那么它们都必须是标准布局类型,并且它们的非静态数据成员必须以相同的类型和相同的顺序出现。
struct { T m; }
只包含一个 T
,但 T
是一个 T
所以它不能包含一个 T
作为它的第一个非静态数据成员。
关于c++ - 幻影类型是否与原始类型具有相同的对齐方式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46425250/