Рассмотрим следующую структуру, содержащую некоторые значения среды:
struct environment_values {
uint16_t humidity;
uint16_t temperature;
uint16_t charging;
};
Я хотел бы добавить дополнительную информацию к этим значениям с типом phantom * и сделать их типы различными в одно и то же время:
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>() …
Поскольку размер тегов с тегами и непомеченных вариантов тоже один и тот же, я думаю, что ответ должен быть да, но я хотел бы иметь определенную уверенность.
* Я не знаю, как эти тегированные значения вызывают в С++. "Сильно типизированные typedefs"? Я взял имя из Haskell.