Поделиться через


Алгоритмы (современный C++)

Для современного программирования на C++ рекомендуется использовать алгоритмы в библиотеке стандартных шаблонов (STL). Далее представлено несколько важных примеров:

  • for_each, который представляет собой алгоритм обхода по умолчанию. (Также transform для семантики "не вместо".)

  • find_if, который представляет собой алгоритм поиска по умолчанию.

  • sort, lower_bound и другие параметры сортировки по умолчанию и алгоритмы поиска.

При создании компаратора по мере возможности используйте строгое неравенство < и именованные лямбда-выражения.

auto comp = []( const widget& w1, const widget& w2 )
      { return w1.weight() < w2.weight(); }

sort( v.begin(), v.end(), comp );

auto i = lower_bound( v.begin(), v.end(), comp );

Циклы

Если возможно, используйте циклы for на основе диапазона или вызовы алгоритма, а не написанные вручную циклы. copy, transform, count_if, remove_if и другие подобные им намного лучше, чем рукописные циклы, поскольку их предназначение очевидно и они облегчают написание кода без ошибок. Кроме того, многие алгоритмы STL имеют оптимизации реализации, которые делают их более эффективными.

Вместо старого C++:

for( auto i = strings.begin(); i != strings.end(); ++i ) {
  :::
  :::
}

auto i = v.begin();

for( ; i != v.end(); ++i ) {
  if (*i > x && *i < y) break;
}

Используйте современный язык C++ следующим образом:

for_each( begin(strings), end(strings), []( string& s ) {
  :::
  :::
} );
auto i = find_if( begin(v), end(v),  [=](int i) { return i > x && i < y; }  );

Циклы "for" на основе диапазона

Цикл for на основе диапазона является функцией языка С++11, а не алгоритма STL. Тем не менее он заслуживает упоминания в этой дискуссии о циклах. Основанные на диапазоне циклы for представляют собой расширение ключевого слова for и являются удобным и эффективным способом записи циклов, выполняющих итерацию с диапазоном значений. Контейнеры, строки и массивы STL готовы для циклов for на базе диапазонов. Чтобы включить этот новый синтаксис итераций для пользовательского типа, добавьте следующую поддержку:

  • Метод begin, возвращающий итератор в начало структуры и метод end, который возвращает итератор в конец структуры.

  • Поддержка в итераторе этих методов: operator*, operator!= и operator++ (версия префикса).

Эти методы могут представлять собой члены или отдельные функции.

Случайные числа

Не секрет, что старая функция CRT rand() имеет много изъянов, которые подробно обсуждаются в сообществе С++. В современном C++ нет необходимости мириться с этим недостатками, равно как и нет необходимости изобретать собственный генератор равномерно распределенных случайных чисел, потому что инструменты для простого и быстрого его создания доступны в STL, как показано в разделе <random>.

См. также

Другие ресурсы

Возвращение к C++ (современный C++)

Справочник по языку C++

Справочник по стандартной библиотеке C++