В C ++ 11 и более поздних версиях по-прежнему оптимально делать «пустую» проверку перед «range for»? - PullRequest
0 голосов
/ 16 октября 2018

В настоящее время я обновляю какой-то старый код C ++, который у меня есть, который перебирает типы контейнеров STL, и я нахожу много такого кода:

if (!edgeSet.empty())
{
  for(typename EdgeSet::const_iterator iter = edgeSet.begin(); iter != edgeSet.end(); iter++)
  {
    ...
  }
}

Который я переворачиваю (успешно)в эквивалент:

if (!edgeSet.empty())
{
  for(auto& edge : edgeSet)
  {
    ...
  }
}

И мне было интересно ... проверка "empty" необходима для "диапазона для"?Я полагаю, что в более старом «стиле итератора» цикла for необходимо избегать бесполезной инициализации и сравнения / ветвления, но мне любопытно, будет ли «range for» автоматически выполнять пустую проверку или нет еще до того, как он запустится.

Далее, если оптимизация действительно происходит, происходит ли она на всех уровнях оптимизации (включая отсутствие оптимизации: -O0)?

Заранее спасибо.

1 Ответ

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

Функция empty() проверяет, нет ли в контейнере элементов, например, begin() == end(), и возвращает true, если контейнер пуст.

на основе диапазона forцикл создает код, эквивалентный следующему

{
  auto && __range = range_expression ; 
  for (auto __begin = begin_expr, __end = end_expr; 
  __begin != __end; ++__begin) { 
    range_declaration = *__begin; 
    loop_statement 
  } 
} 

Управляющее выражение в цикле for равно is __begin != __end.Вы можете увидеть чек в empty() и чек здесь эквивалентны.Таким образом, нет необходимости для дополнительной проверки empty() перед использованием цикла for на основе диапазона.

...