﻿# V2674\. MISRA\. The argument to 'std::move' should be a non\-const lvalue\.

Диагностическое правило основано на руководстве [MISRA](https://misra.org.uk/) \(Motor Industry Software Reliability Association\) по разработке программного обеспечения\.

Правило актуально только для C\+\+\.

Применение [`std::move`](https://timsong-cpp.github.io/cppwp/n4950/forward#lib:move,function) к объекту типа `const T` приводит к выведению типа `const T&&`\. Данный тип при идеальной передаче не приведёт в итоге к вызову конструктора или оператора перемещения, так как их сигнатуры требуют изменяемую rvalue\-ссылку `T&&`\. В соответствии с правилами разрешения перегрузки функций, компилятор выберет конструктор копирования \(если он доступен\)\. В итоге вместо перемещения ресурсов происходит скрытое копирование объекта\.

Некорректный код:

```cpp
void archiveData()
{
  std::vector<std::string> archive;
  const std::string technicalId = ....;
  // ....
  archive.push_back(std::move(technicalId));
}
```

Переменная `technicalId` имеет квалификатор `const`, из\-за чего результат `std::move(technicalId)` будет иметь тип `const std::string&&`\. Вследствие этого при разрешении перегрузки [`std::vector<std::string>::push_back`](https://timsong-cpp.github.io/cppwp/n4950/vector.modifiers#lib:insert,vector) будет выбрана версия, принимающая `const std::string &` и ведущая к копированию строки\.

Исправить код можно следующими способами\.

**Способ N1**\. Если нет возможности опустить константность перемещаемого объекта, то вызов `std::move` стоит удалить:

```cpp
void archiveData()
{
  std::vector<std::string> archive;
  const std::string technicalId = ....;
  // ....
  archive.push_back(technicalId);
}
```

**Способ N2**\. Опустить константность объекта:

```cpp
void archiveData()
{
  std::vector<std::string> archive;
  std::string technicalId = ....;
  // ....
  archive.push_back(std::move(technicalId));
}
```

Удаление квалификатора `const` меняет результирующий тип выражения на `std::string &&`\. Это позволяет компилятору успешно выбрать перегрузку `std::vector<std::string>::push_back`, принимающую `std::string &&`, которая в свою очередь заберёт ресурсы из переданного объекта\.