Переменная цикла основанной на диапазоне for
цикл копируется из элементов области значений вместо ссылки, что приводит к неэффективному коду
Этот дефект возникает, когда переменный цикл основанная на диапазоне for
цикл копируется из элементов области значений вместо чтения элементов области значений по ссылке. Скопируйте элементы области значений только тогда, когда это необходимо, поскольку их копирование может привести к неэффективному коду. Этот дефект возникает, когда переменная цикла не изменена, и любое из этих условий верно:
Скопированная переменная цикла является большой тривиально копируемой переменной типа. Копирование тривиально копируемого объекта дороже, чем ссылка на него, когда объект велик.
Скопированная переменная цикла является нетривиально копируемым типом. Копирование такого объекта может потребовать вызова внешней функции, что дороже, чем ссылки на него. Чтобы проверить, является ли объект нетривиально копируемым, используйте функцию std::is_trivially_copyable
. Для получения дополнительной информации об этой функции см. std::is_trivially_copyable
в ссылке C++.
Диапазонные for
циклы могут стать неэффективными, когда в каждой итерации цикла выполняется дорогая копия переменной цикла. Рассмотрим этот код:
void foo( std::map<std::string, std::string> const& property_map ) { for( std::pair< const std::string, std::string > const property: property_map) {} }
Переменная цикла property
объявлен как const
вместо const&
. В каждой итерации for
цикл, std::pair
объект копируется с карты property_maps
в переменную цикла property
. Из-за пропавшего &
в объявлении propert
операция дорогостоящего копирования выполняется в каждой итерации вместо операции ссылки, что приводит к неэффективному коду. Потому что этот код компилируется и функционирует правильно, неэффективно for
циклы могут не быть замечены. Для аналогичного источника неэффективности смотрите Expensive pass by value
и Expensive return by value
.
Чтобы исправить этот дефект, объявите переменную цикла основанной на диапазоне for
цикл как const&
. Рассмотрим этот код:
void foo( std::map<std::string, std::string> const& property_map ) { for( std::pair< const std::string, std::string > const& property: property_map) {} }
property
объявлен как const&
переменная ссылается на другой элемент карты property_map
в каждой итерации цикла, без копирования какого-либо ресурса. Предотвращая дорогостоящую копию в каждой итерации, код становится более эффективным.Эффективность улучшения могут варьироваться в зависимости от используемого компилятора, реализации библиотеки и окружения.
Группа: Эффективность |
Язык: C++ |
По умолчанию: Off |
Синтаксис командной строки
: EXPENSIVE_RANGE_BASED_FOR_LOOP_ITERATION |
Влияние: Средний |
Expensive local variable copy
| Expensive pass by value
| Expensive return by value
| Find defects (-checkers)