Диагностическое правило основано на руководстве MISRA (Motor Industry Software Reliability Association) по разработке программного обеспечения.
Правило актуально только для C++.
Применение std::move к объекту типа const T приводит к выведению типа const T&&. Данный тип при идеальной передаче не приведёт в итоге к вызову конструктора или оператора перемещения, так как их сигнатуры требуют изменяемую rvalue-ссылку T&&. В соответствии с правилами разрешения перегрузки функций, компилятор выберет конструктор копирования (если он доступен). В итоге вместо перемещения ресурсов происходит скрытое копирование объекта.
Некорректный код:
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 будет выбрана версия, принимающая const std::string & и ведущая к копированию строки.
Исправить код можно следующими способами.
Способ N1. Если нет возможности опустить константность перемещаемого объекта, то вызов std::move стоит удалить:
void archiveData()
{
std::vector<std::string> archive;
const std::string technicalId = ....;
// ....
archive.push_back(technicalId);
}
Способ N2. Опустить константность объекта:
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 &&, которая в свою очередь заберёт ресурсы из переданного объекта.
Была ли полезна эта страница документации?
Мы ответим вам на:
Если вы так и не получили ответ, пожалуйста, проверьте, отфильтровано ли письмо в одну из следующих стандартных папок: