Информация об изменениях

Сообщение Re[4]: Placement new для инициализации примитивного типа в с от 07.10.2025 3:56

Изменено 07.10.2025 6:11 so5team

Re[4]: Placement new для инициализации примитивного типа в самодельном union?
Здравствуйте, _NN_, Вы писали:

S>>Скорее как std::variant но без хранения значения index, т.к. что за тип лежит внутри variant-а по косвенным признакам снаружи знает объект, который этим variant-ом и владеет. Собственно, владелец отвечает и за корректное удаление, и за корректное копирование/перемещение.


_NN>variant из одного типа и есть optional.

_NN>Или там предполагаются разные типы ?

Ситуация какая-то такая:
template<typename T>
struct data_chunk_t;

template<typename T>
class my_union_t
{
  using ptr_t = data_chunk_t<T>;

  alignas( std::max( alignof(T), alignof(ptr_t) ) )
  std::array< std::byte, std::max( sizeof(T), sizeof(ptr_t) ) > _content;
  ...
};

template<typename T>
class data_item_t
{
  data_description_t _desc;
  my_union_t<T> _value_or_child_chunk;
  ...
};

template<typename T>
struct data_chunk_t
{
  ...
  std::vector< data_item_t<T> > _data;
  ...
};


Соответственно, в my_union_t может быть либо T, либо указатель на data_chunk_t<T>. Либо, в результате конструктора/оператора перемещения, там может ничего не оказаться. Что именно лежит в data_item_t::_value_of_child_chunk однозначно определяется по содержимому data_item_t::_desc.

_NN>А чего бы не обобщить ?


Потому что приходится решать конкретную задачу, в рамках которой обобщенное программирование задействуется только в той степени, в которой оно нужно для решения задачи. Если бы делалась какая-то библиотека для повторного использования в разных условиях, то тогда был бы и другой разговор.

PS. std::variant не используется потому, что содержимое data_item_t формируется так, чтобы там не было разных лишних данных на современных 64-х битовых платформах. Грубо говоря, сейчас размер data_item_t и выравнивание для него кратны 8. Меняешь my_union на std::variant, появляется, как минимум, лишний байт, который увеличивает размер data_item_t еще на 8 байт (с учетом выравнивания). А т.к. этих data_item_t десятки миллионов, минимум, то лишние 8 байт ведут к десяткам миллионов лишних мегабайт занятой ОП.
Re[4]: Placement new для инициализации примитивного типа в с
Здравствуйте, _NN_, Вы писали:

S>>Скорее как std::variant но без хранения значения index, т.к. что за тип лежит внутри variant-а по косвенным признакам снаружи знает объект, который этим variant-ом и владеет. Собственно, владелец отвечает и за корректное удаление, и за корректное копирование/перемещение.


_NN>variant из одного типа и есть optional.

_NN>Или там предполагаются разные типы ?

Ситуация какая-то такая:
template<typename T>
struct data_chunk_t;

template<typename T>
class my_union_t
{
  using ptr_t = data_chunk_t<T>;

  alignas( std::max( alignof(T), alignof(ptr_t) ) )
  std::array< std::byte, std::max( sizeof(T), sizeof(ptr_t) ) > _content;
  ...
};

template<typename T>
class data_item_t
{
  data_description_t _desc;
  my_union_t<T> _value_or_child_chunk;
  ...
};

template<typename T>
struct data_chunk_t
{
  ...
  std::vector< data_item_t<T> > _data;
  ...
};


Соответственно, в my_union_t может быть либо T, либо указатель на data_chunk_t<T>. Либо, в результате конструктора/оператора перемещения, там может ничего не оказаться. Что именно лежит в data_item_t::_value_of_child_chunk однозначно определяется по содержимому data_item_t::_desc.

_NN>А чего бы не обобщить ?


Потому что приходится решать конкретную задачу, в рамках которой обобщенное программирование задействуется только в той степени, в которой оно нужно для решения задачи. Если бы делалась какая-то библиотека для повторного использования в разных условиях, то тогда был бы и другой разговор.

PS. std::variant не используется потому, что содержимое data_item_t формируется так, чтобы там не было разных лишних данных на современных 64-х битовых платформах. Грубо говоря, сейчас размер data_item_t и выравнивание для него кратны 8. Меняешь my_union на std::variant, появляется, как минимум, лишний байт, который увеличивает размер data_item_t еще на 8 байт (с учетом выравнивания). А т.к. этих data_item_t десятки миллионов, минимум, то лишние 8 байт ведут к десяткам лишних мегабайт занятой ОП.