Это запах кода использовать std :: move для всех копий значений класса на всякий случай?

У меня есть функция, которая получает структуру конфигурации, которая на данный момент представляет собой просто структуру, содержащую массив

class ShmConfig {
public:
   std::int64_t shellShmSize[ShellId_Count];
};

И я передаю его другой функции в функции с std::move, потому что я хочу, чтобы все места кода, которые его копируют, не зависели от того факта, что его можно эффективно скопировать.

m_allocator.setup(std::move(config));

Если позже его можно будет более эффективно переместить (возможно, потому, что я добавлю к нему std::string), он автоматически станет более эффективным. Но clang-tidy не советует

std::move переменной 'config' тривиально копируемого типа 'ShmConfig' не имеет никакого эффекта; удалить std::move()

Не понимаю, почему это желательно. Есть ли недостаток в оборачивании move? Следует ли следовать этим советам только в том случае, если кто-то регулярно запускает clang-tidy, чтобы можно было обнаружить случаи, когда std::move будет иметь смысл позже, после добавления элементов данных?


person Johannes Schaub - litb    schedule 18.05.2021    source источник
comment
в целом код не зависит от того, был перемещен объект или нет. Зависит от того, используете ли вы config после std::move(config)   -  person 463035818_is_not_a_number    schedule 18.05.2021
comment
Поскольку ShmConfig не имеет управляемых ресурсов, move семантика не будет иметь значения. Добавление std::move на всякий случай, что в какой-то будущей версии ShmConfig будет перемещаться ресурс переменных-членов, похоже на преждевременную оптимизацию. ЯГНИ.   -  person Eljay    schedule 18.05.2021
comment
Я не согласен с clang-tidy. std::move имеет очень заметный эффект. Это говорит мне в будущем, что меня больше не волнует значение переменной, и я не должен использовать его, кроме как для повторного присвоения. Это та явная аннотация, которая даже допускает оптимизацию, связанную с перемещением. Жалко, что он назывался move, а не may_move_now. Думаю, последнее было не таким уж броским.   -  person StoryTeller - Unslander Monica    schedule 18.05.2021
comment
Я чувствую, что должен также отметить, что clang-tidy иногда может давать не самый лучший совет stackoverflow.com/q/52871026/817643   -  person StoryTeller - Unslander Monica    schedule 18.05.2021
comment
Некоторые классы (например, unique_ptr) идут с определенными состояниями перемещения. Нередко проверять состояние перемещения из объекта как сигнал о том, что объект уже был использован. Кто-то, привыкший к этому шаблону, может сделать /* set up if not already set up */ if (is_ready(config)) m_allocator.setup(std::move(config)), чтобы определить, использовалась ли конфигурация предыдущим вызовом setup. (Чаще встречается, если ShmConfig имеет operator bool() преобразование.) В предупреждении говорится: «Эй, этот объект может вести себя не так, как вы ожидаете».   -  person Raymond Chen    schedule 18.05.2021
comment
@Eljay Adding std::move just in case some future version: Но это не только преждевременная оптимизация, это семантика. Как разработчик, вы хотите выразить что-то концептуально, полностью правильно на более абстрактном уровне. Я полностью согласен с StoryTeller здесь, что источник путаницы кроется в вводящей в заблуждение терминологии, выбранной для std::move. По крайней мере, для классов / структур, которые, вероятно, могут быть изменены / расширены в будущем, я думаю, следует предпочесть правильную семантику ограничению кода эффективному поведению компилятора.   -  person Secundi    schedule 27.05.2021
comment
WG21, вероятно, выбрала std::move, потому что std::permission_to_transplant_innards_leaving_the_original_object_in_a_valid_but_unspecified_state может быть слишком многословным.   -  person Eljay    schedule 27.05.2021
comment
Я не сказал, что поиск правильного наименования здесь будет легкой задачей ... :) Но поскольку std::move вообще ничего не перемещает, кроме упомянутых здесь проблем, вполне разумно пересмотреть терминологию.   -  person Secundi    schedule 28.05.2021
comment
@Sec действительно std::forward продвигает вперед или просто выполняет приведение?   -  person Johannes Schaub - litb    schedule 28.05.2021
comment
Правильно ли это описание cppreference? эта перегрузка пересылает аргумент другой функции с той категорией значения, которую он имел при передаче вызывающей функции .. Ярость!   -  person Johannes Schaub - litb    schedule 28.05.2021
comment
Это (почти?) Всегда вопрос баланса, с чего начать с упрощений с точки зрения терминологии. Так как наименования std::move и std::forward здесь по-прежнему являются неплохим компромиссом с несколькими исключительными случаями, когда вам нужно переосмыслить их фактическое поведение, clang-tidy слишком остро реагирует здесь, поскольку это относится исключительно к эффективному поведению без необходимого внимания к семантике. Это как-то не совсем следствие, поскольку он (?) Жалуется не на фактическое приведение, а на сам вызов метода, который на самом деле является исключительно семантической оболочкой.   -  person Secundi    schedule 28.05.2021
comment
С точки зрения ответственности, я думаю, здесь все может стать намного яснее. Представьте себе сложный логический уровень, который обрабатывает массу (возможно, сгенерированных) структур / интерфейсов. Как соответствующий разработчик логики, вы можете пообещать семантику перемещения для нескольких ее частей. Поскольку операция четко определена даже для POD, она может не повлиять на производительность по сравнению с копиями для всех сомнительных случаев, нет никакой пользы от предоставления возможно сложного ветвления здесь для этих случаев, а только недостатки (шаблон ...) под вопросом, для сортов, которые на самом деле не вызывают сомнений   -  person Secundi    schedule 28.05.2021
comment
Clang-tidy должен сосредоточиться на действительно важных случаях, например, на обработке возвращаемого значения в сочетании с std::move, где влияние на производительность может быть значимым, теоретически и практически.   -  person Secundi    schedule 28.05.2021
comment
Во многих других случаях он слишком остро реагирует. Например, если я делаю std :: move, а тип параметра назначения - const T, и он рекомендует отбросить std :: move, потому что поведение такое, как если бы я его пропустил. ИМО плохие рекомендации! Поэтому я подозреваю, что он должен запускаться достаточно часто, чтобы он предлагал добавить его снова, когда это необходимо.   -  person Johannes Schaub - litb    schedule 28.05.2021