Можно ли изменить или улучшить этот код C ++ с помощью семантики перемещения? - PullRequest
0 голосов
/ 29 октября 2018
struct big_struct{
    vector<int> a_vector;
    map<string, int> a_map;
};

big_struct make_data(){
    big_struct return_this;
    // do stuff, build that data, etc
    return return_this;
}
int main(){

    auto data = make_data();
}

Я видел семантику перемещения, примененную к конструкторам, но в этом фрагменте кода мне интересно, полностью ли копируется большая структура при возвращении или нет. Я даже не уверен, что это связано с семантикой перемещения. Всегда ли С ++ копирует данные такого типа или они оптимизированы? Может ли этот код быть изменен или улучшен?

А как насчет функции, которая возвращает вектор или карту? Эта карта / вектор скопированы?

Ответы [ 2 ]

0 голосов
/ 29 октября 2018

Как указано здесь , ваш класс на самом деле имеет конструктор перемещения (неявно сгенерированный), поэтому его не следует копировать в код, по крайней мере, один раз (в main).

Одна проблема состоит в том, что то, на что вы полагаетесь, называется NRVO , и компиляторам * * не требуется для его реализации (в отличие от более счастливого, более простого брата, RVO.) Итак, ваша структура есть шанс, очень маленький, чтобы быть скопированным в операторе return, но такой маленький, что возврат за ходом (как return std::move(return_this);) фактически никогда не рекомендуется. Скорее всего, NRVO действительно будет применяться, если в вашей функции действительно есть один оператор return, который возвращает один именованный объект.

0 голосов
/ 29 октября 2018

Вам не нужно ничего менять. Сейчас у вас есть правило нуля . Поскольку и std::map, и std::vector являются подвижными, ваш класс автоматически получает операции перемещения.

Так как return_this является локальным объектом функции, он будет рассматриваться как значение r, и он будет либо перемещен за вас, либо NRVO включится, и перемещение или копирование не произойдет.

Ваш код либо создаст вызов конструкции по умолчанию для return_this и вызов конструктора перемещения для data, либо вы увидите один вызов конструктора по умолчанию для data (NRVO делает return_this и data одинаковыми вещь).

...