Я часто использую контейнеры STL, но никогда не использовал алгоритмы STL, которые должны использоваться с контейнерами STL.
Одно преимущество использования алгоритмов STL - то, что они предоставляют метод для удаления циклов так, чтобы логическая сложность кода была уменьшена. Существуют другие преимущества, которые я не перечислю здесь.
Я никогда не видел, что C++ кодирует, который использует алгоритмы STL. Из примера кода в статьях веб-страницы к проектам с открытым исходным кодом я не видел их использование.
Они используются более часто, чем это кажется?
Краткий ответ: Всегда.
Длинный ответ: Всегда. Вот для чего они нужны. Они оптимизированы для использования с контейнерами STL, они быстрее, понятнее и идиоматичнее, чем все, что вы можете написать самостоятельно. Единственная ситуация, в которой вы должны подумать о том, чтобы использовать собственную, - это если вы можете сформулировать очень конкретную критически важную потребность, которую алгоритмы STL не удовлетворяют.
Отредактировано для добавления: (Хорошо, не совсем , действительно всегда, но если вам нужно спросить, следует ли вам использовать STL, ответ - «да».)
Вы уже получили несколько ответов, но я не могу согласиться ни с одним из них. Некоторые из них довольно близки к цели, но не упоминают ключевой момент (IMO, конечно).
По крайней мере, для меня ключевой момент довольно прост: вы должны использовать стандартные алгоритмы, когда они помогают прояснить код , который вы пишете.
Это действительно так просто. В некоторых случаях то, что вы делаете, потребует тайного вызова с использованием std :: bind1st
и std :: mem_fun_ref
(или что-то в этом роде), которое чрезвычайно плотно и непрозрачно, где цикл для
был бы почти тривиально простым и понятным. В таком случае используйте цикл для
.
Если нет стандартного алгоритма, который делает то, что вы хотите, проявите осторожность и посмотрите еще раз - вы часто упускаете то, что действительно будет делать то, что вы хотите (одно место, которое часто упускают: алгоритмы из
часто полезны для нечисловых целей). Посмотрев пару раз и подтвердив, что действительно не стандартный алгоритм, чтобы делать то, что вы хотите, вместо того, чтобы писать этот for
цикл (или что-то еще) в строке, подумайте о написании общего алгоритм, чтобы делать то, что вам нужно. Если вы используете его в одном месте, есть довольно хороший шанс, что вы сможете использовать его еще в двух или трех местах, и в этот момент это может быть большим выигрышем в ясности.
Написание общих алгоритмов не так уж и сложно - на самом деле, это часто почти не требует дополнительной работы по сравнению с написанием встроенного цикла, поэтому, даже если вы можете использовать его только дважды, вы уже сэкономите немного работы, даже если вы проигнорируете улучшение читабельности и ясности кода.
Есть много хороших алгоритмов помимо таких вещей, как std :: foreach
.
Однако существует множество нетривиальных и очень полезных алгоритмов:
std :: sort
, std :: upper_bound
, std :: lower_bound
, std :: binary_search
std :: max
, std :: min
, std :: partition
, std :: min_element
, std :: max_element
std :: find
, std :: find_first_of
и т. Д. И многие другие.
Такие алгоритмы, как std :: transform
, очень полезны с лямбда-выражениями C ++ 0x или подобными boost :: lambda
или boost :: bind
Я пишу критически важные для производительности приложения. Это те вещи, которые должны обрабатывать миллионы фрагментов информации как можно быстрее. Я не смог бы делать некоторые вещи, которые я делаю сейчас, если бы не STL. Используйте их всегда.
Если бы мне нужно было что-то написать сегодня днем, и я знал бы, как это сделать, используя ручные циклы, и мне нужно было бы выяснить, как это сделать в алгоритмах STL, я бы написал это, используя ручные циклы.
Сказав это, я буду работать над тем, чтобы сделать алгоритмы STL надежной частью моего набора инструментов по причинам, изложенным в других ответах.
-
Причины, по которым вы можете не увидеть это в коде, заключаются в том, что это либо устаревший код, либо написанный устаревшими программистами. У нас было около 20 лет программирования на C ++ до того, как появился STL, и к тому моменту у нас было сообщество программистов, которые знали, как делать что-то по-старому, и еще не изучили метод STL. Скорее всего, это останется на целое поколение.
Единственный раз, когда я не использую алгоритмы STL, - это когда различия межплатформенной реализации влияют на результат моей программы. Такое случалось только в одном-двух редких случаях (на Playstation 3). Хотя интерфейс STL стандартизирован для разных платформ, реализация - нет.
Кроме того, в некоторых чрезвычайно высокопроизводительных приложениях (например, видеоигры, серверы видеоигр) мы заменили некоторые структуры STL на наши собственные, чтобы добиться большей эффективности.
Однако в подавляющем большинстве случаев использование STL - это правильный путь. А в других моих работах (не связанных с видеоиграми) я использовал исключительно STL.
Я бы не стал использовать STL в двух случаях:
Когда STL не предназначен для вашей задачи. STL является почти лучшим для общих целей. Однако для конкретных приложений STL не всегда может быть лучшим. Например, в одной из моих программ мне нужна огромная хэш-таблица, а эквивалент хэш-таблицы STL/tr1 занимает слишком много памяти.
Когда вы изучаете алгоритмы. Я один из немногих, кому нравится изобретать колеса и многому учиться в этом процессе. Для этой программы я заново реализовал хэш-таблицу. Это действительно заняло у меня много времени, но в конце концов все усилия окупились. Я научился многим вещам, которые очень пригодятся в моей будущей карьере программиста".
Основная проблема с алгоритмами STL до сих пор заключалась в том, что, хотя сам вызов алгоритма более понятен, определение функторов, которые вам нужно будет передать им, сделает ваш код длиннее и сложнее из-за того, как язык заставил вас это сделать. Ожидается, что C++ 0x изменит это, поддерживая лямбда-выражения.
Я активно использую STL в течение последних 6 лет, и хотя я пытался использовать алгоритмы STL везде, где мог, в большинстве случаев это делало мой код более неясным, поэтому я вернулся к простому циклу. Теперь с C++ 0x все наоборот, код, кажется, всегда выглядит проще с ними.
Проблема в том, что к настоящему времени поддержка C++ 0x все еще ограничена несколькими компиляторами, даже потому, что стандарт еще не полностью закончен. Так что, вероятно, нам придется подождать несколько лет, чтобы действительно увидеть широкое использование алгоритмов STL в производственном коде.
Имейте в виду, что алгоритмы STL охватывают множество основ, но большинство разработчиков C ++, вероятно, закодируют что-то, что делает что-то эквивалентное std :: find ()
, std :: find_if ()
и std :: max ()
почти каждый день их работы (если они уже не используют версии STL). Используя версии STL, вы отделяете алгоритм как от логической последовательности кода, так и от представления данных .
Для других менее часто используемых алгоритмов STL, таких как std :: merge ()
или std :: lower_bound ()
, это очень полезные процедуры (первая для слияния двух отсортированных контейнеров , второй для определения, куда вставить элемент в контейнер, чтобы он оставался упорядоченным). Если бы вы попытались реализовать их самостоятельно, то, вероятно, потребовалось бы несколько попыток (алгоритмы несложные, но вы, вероятно, получите постепенные ошибки или что-то подобное).
Я сам использую их каждый день своей профессиональной карьеры. Некоторые устаревшие кодовые базы, предшествующие стабильному STL, могут не использовать его так широко, но если есть новый проект, который намеренно избегает этого, я склонен думать, что это был хакер, работавший неполный рабочий день, который все еще работал в соответствии с предположением середины 90-х, что шаблоны работают медленно, и поэтому их следует избегать.
Когда следует использовать алгоритмы STL вместо собственных?
Когда вы цените свое время и рассудок и получаете больше удовольствия, чем изобретать колесо снова и снова.
Вам нужно использовать свои собственные алгоритмы, когда этого требует проект, и нет приемлемых альтернатив написанию материала самостоятельно, или если вы определили алгоритм STL как узкое место (конечно, с помощью профилировщика), или имеете какие-то ограничения STL не соответствует, или адаптация STL для задачи займет больше времени, чем написание алгоритма с нуля (мне приходилось использовать скрученную версию двоичного поиска несколько раз ...). STL не идеален и подходит не для всего, но когда есть возможность, вы должны его использовать. Когда кто-то уже сделал за вас всю работу, часто нет причин делать то же самое снова.
Используются ли они чаще, чем кажется?
Я никогда не видел, чтобы их использовали; кроме книг. Может быть, они используются в реализации самого STL. Возможно, они станут более популярными из-за простоты использования (см., Например, Лямбда-функции и выражения ), или даже станут устаревшими (см., Например, Цикл for на основе диапазона ), в следующей версии C ++.
Алгоритмы STL следует использовать всякий раз, когда они подходят для ваших задач. Что почти всегда.
Когда вы думаете, что можете написать код лучше, чем действительно умный программист, который потратил недели на исследования, тестирование и попытки справиться со всеми мыслимыми наборами входных данных.
Для большинства землян ответ - НИКОГДА!