Я наткнулся на большую структуру пода, в которую хотел добавить член std::vector.
struct LargePodStruct {
float x,y,z;
int *arr;
int sz;
... // dozens of primitive types
std::vector<int> the_new_vector;
};
Чтобы добавить vector в эту структуру, мне нужно было заменить все экземпляры calloc() этой структуры на new.
Кроме того, мне нужно обнулить каждый существующий член. Однако добавление конструктора по умолчанию, который обнуляет каждый член, - это обычная задача. Также легко забыть создать экземпляр нового члена в будущем.
LargePodStruct::LargePodStruct()
x(), y(), z(), arr(), sz(), ... // +dozens of instantiations
{}
Есть ли более простой способ создать экземпляры примитивных членов этой структуры с меньшими усилиями?
Есть ли хороший и элегантный способ создать нулевой экземпляр члена союза?
.
struct LargePodStruct {
float x,y,z;
int *arr;
int sz;
...
union {
int i;
void *ptr;
} u;
std::vector<int> the_new_vector;
};
Рассмотрите возможность добавления инициализатора члена по умолчанию для всех ваших членов, таких как int * arr = nullptr; и int sz = 0;, непосредственно в определении класса.
Начиная с C++ 11 вы можете напрямую инициализировать их в их объявлении, например: int sz = 0;
Несвязанный: в зависимости от того, на что указывает int *arr;, вам может потребоваться соблюдать Правило трех. Может быть, и эту присоску будет проще vector-ize.
@ FrançoisAndrieux, если моя структура также содержала вложенный union (скажем, целые числа и указатели), есть ли способ также обнулить объединение, используя этот синтаксис?
@GrimFandango Я с ним не знаком, но описано здесь.
Является ли C++ 98 обязательным?
@kiner_shah, (+1) ваше предложение - единственная альтернатива для C++ 98.
@HolyBlackCat, это для меня, но мне также любопытно, как этот случай сейчас обрабатывается.
Нельзя ли заменить пару {arr, sz} вектором?





Вы мог продолжаете выделять необработанный блок памяти с помощью calloc(), а затем используете размещение-новое для создания структуры внутри этого блока памяти:
void *buffer = calloc(1, sizeof(LargePodStruct));
LargePodStruct *s = new(buffer) LargePodStruct;
Однако вы не сможете использовать delete для освобождения структуры, вы должны вызвать ее деструктор напрямую, а затем free() блок памяти:
s->~LargePodStruct();
free(buffer);
Почему нет ? Все равно delete не вызовет free()?
@GrimFandango не гарантируется, нет, точно так же, как new не гарантирует внутреннего использования malloc(). Вы должны правильно сопоставить распределители с их задокументированными фриперами, иначе поведение будет неопределенным.
template<typename V>
struct zdf{
V value;
zdf():value{}{};
operator V&(){return value;};
operator V()const{return value;};
V operator()const{return value;};
V& operator(){return value};
};
struct LargeModernValue{
zdf<float> x,y,z;
std::vector<int> arr;
std::any u;/*std::variant<int,void*> u;*/
//....
std::vector<int> theNewVec;
};
Вы можете попробовать
memset()!