Мне нужно создать список структур размером 1024. Поэтому я пытаюсь оптимизировать операцию вставки в список, используя семантику перемещения. Но семантика перемещения имеет смысл только для памяти, выделенной кучей (насколько мне известно). Может ли кто-нибудь предложить мне лучший способ сделать это. это мой код
#include <iostream>
#include <list>
struct St {
int32_t arr[1024];
};
int main() {
std::list<St> struct_list;
for(int32_t i = 0; i < 1024; ++i) {
St st; // stack allocated and memory gets deallocated after each loop
std::cout << &st << std::endl;
struct_list.emplace_back(std::move(st)); // I feel std::move doesn't make any sense here even if I implement move constructor, still data gets copied into the std::list which is allocated in heap, so not efficient.
std::cout << &struct_list.back() << "\n" << std::endl;
}
return EXIT_SUCCESS;
}
«Но семантика перемещения имеет смысл только для памяти, выделенной кучей». Не могли бы вы указать, откуда вы это взяли?
Учитывая ваше текущее определение St
:
struct St {
int32_t arr[1024];
};
Технически перемещение и копирование обоих результатов одинаково для этого конкретного определения St
.
Тем не менее, семантически имеет смысл пометить st
для перемещения, когда вы закончите с ним, и st
все равно будет уничтожено. Например, если вы позже решите изменить определение St
на что-то вроде:
struct St {
std::vector<int32_t> vec;
};
Тогда это будет иметь значение — элемент векторных данных будет перемещен, а не скопирован.
Короче говоря, я рекомендую сосредоточиться на семантике операции перемещения, т. е. имеет ли смысл перемещать объект? Что ж, если вы все равно собираетесь избавиться от объекта, то, скорее всего, это произойдет.
Если вам удастся перейти на C++17, вы можете использовать возвращаемое значение emplace_back, чтобы сначала добавить его в список, а затем заполнить.
Вы можете (если это возможно по умолчанию, как в вашем примере) сначала emplace_back создать новый экземпляр, а затем использовать .back()
, чтобы получить его и заполнить.
Выделение и освобождение стека не требует больших затрат, особенно для POD. Важна логика, которую вы применяете к этому.
Что касается перемещения, для этого примера std::move будет делать то же самое, что и копирование, так что нет, вам это не нужно. Однако, если бы это был массив std::string
, std::move позволил бы вам перемещать строки из одного массива в другой.
Что заставляет вас думать, что не должно?