Имеет ли смысл std::move в переменной стека

Мне нужно создать список структур размером 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;
}

Что заставляет вас думать, что не должно?

πάντα ῥεῖ 26.12.2020 15:08

«Но семантика перемещения имеет смысл только для памяти, выделенной кучей». Не могли бы вы указать, откуда вы это взяли?

πάντα ῥεῖ 26.12.2020 15:10
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
2
628
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Учитывая ваше текущее определение 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 позволил бы вам перемещать строки из одного массива в другой.

Другие вопросы по теме