Подтвердить что ты не робот

Что такое STL?

Я не программист на С++ и с трудом понимаю объяснения, данные на сайтах. Я не понимаю контейнеры или итераторы и не планирую изучать С++ в ближайшем будущем. Итак, в непрофессиональных терминах: что такое STL и что он может сделать для меня? Как он сравнивается с чем-то вроде библиотеки Python Standard или glibc?

4b9b3361

Ответ 1

Чтобы понять STL, вам нужно будет хотя бы понять некоторые аспекты С++. Я попытаюсь изо всех сил объяснить это. Структура обманчиво проста. Там, где библиотека сияет, используется то, как ее использование может упростить многие сложные задачи. Я собираюсь придерживаться некоторых очень простых примеров, хотя и потому, что что-то еще, вероятно, смутит кого-то, кто не знает С++, и потому, что я не хочу писать роман.;)

Во-первых, какая-то история. STL (стандартная библиотека шаблонов) была разработана отдельно, а затем представлена ​​на рассмотрение стандартного комитета С++, предоставляя им возможность использовать ее на языке. Но он не был разработан как часть стандарта С++, и по этой причине он разработан в стиле, который сильно отличается от остальной части стандартной библиотеки С++. Если я помню свою древнюю историю, она также приняла стандартный комитет, чтобы понять STL и привыкнуть к нему. Когда они изначально видели это, они не слишком увлекались этим, но через некоторое время осознали, насколько мощным и продуманным он был. Поэтому он был принят на язык. Все это произошло еще в конце 1990-х годов, поскольку язык приближался к стандартизации ИСО.

В своей основе STL обеспечивает наиболее фундаментальную функциональность, которую вы ожидаете от стандартной библиотеки: возможность хранения последовательностей данных и возможность обработки этих последовательностей.

Каждый другой язык имеет часть своей стандартной библиотеки Collections/Containers, содержащую реализации динамических массивов (известных как arraylists в Java, List in С# и векторы на С++), связанные списки, словари и другие общие структуры данных.

Они также обычно предоставляют некоторые механизмы для перемещения этих структур. (Например, перечисления или итераторы)

STL предоставляет ту же функциональность на С++, но делает это необычно элегантным способом и с некоторыми интересными абстракциями.

STL полностью разделяется на три отдельных компонента:

  • Контейнеры (как описано выше, на каждом языке есть такие: Arrays, ArrayList, Dictionary, Set, LinkedList и т.д. Любая структура данных, которая может хранить коллекцию объектов, является контейнером на С++)
  • Алгоритмы (каждый язык также имеет их в некоторой форме. Алгоритмы - это функции для обработки последовательностей элементов.) Предположим, что последовательность - это контейнер. Это немного упрощение, но мы доберемся до этого. Алгоритмы служат для широкого круга целей: от функции for_each(), которая позволяет применять функцию к каждому элементу в последовательности или связанному с ним transform(), который применяет функцию к каждому элементу и сохраняет результат в отдельной последовательности (очень похож на работу карты в функциональных языках) или накапливать (подобно сгибам на функциональных языках), но также сортировать или искать функции и функции, которые позволяют копировать целые последовательности.
  • И, наконец, клей, который связывает контейнеры и алгоритмы вместе: Итераторы. Как я сказал выше, последовательности (которые работают над алгоритмами) не совсем такие же, как контейнеры. Элементы в контейнере, безусловно, представляют собой последовательность, но первые пять элементов в контейнере также являются последовательностью. Или любой другой элемент в контейнере представляет собой последовательность. Данные, считанные непосредственно из потока файлов, могут рассматриваться как последовательность. Даже данные, которые генерируются "на лету" (скажем, последовательность фибоначчи), можно рассматривать как последовательность значений. Последовательности не должны сопоставляться с контейнером или даже с данными, которые существуют в памяти, хотя это наиболее распространенное использование.

Обратите внимание, что это не перекрытие между этими тремя областями. Контейнер хранит (и владеет) данные и создает итераторы. Итераторы позволяют проверять, изменять и перемещать данные. И алгоритмы работают на диапазонах итераторов

Концептуально говоря, итератор имеет две функции. Он указывает на некоторые данные и может перемещаться в последовательности (в зависимости от типа итератора могут быть доступны разные операции перемещения. Почти все итераторы могут перейти к следующему элементу. Некоторые из них также могут перемещаться в предыдущие, а некоторые могут прыгать произвольными расстояниями назад и вперед). Если вы знакомы с C, это будет звучать очень похоже на указатели, и это не случайно. Итераторы моделируются как обобщение указателей, и на самом деле указатели также являются действительными итераторами. Все алгоритмы STL работают с указателями, а также с "настоящими" итераторами.

Это означает, что любая последовательность данных может быть представлена ​​парой итераторов: первый итератор указывает на первый элемент в последовательности, а второй - один за концом последовательности.

Это позволяет довольно простой синтаксис для чередования последовательностей в цикле:

std::vector<int> container;
for (iter it = container.begin(); it != container.end(); ++it)
{
  // perform some operations on the iterator (it) or the element it points to (*it)
  ++(*it); // increment the value the iterator points to
}

Или мы можем применить алгоритм к последовательности:

std::sort(container.begin(), container.end());

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

Мы можем обобщить функцию сортировки бит, предоставив нашу собственную функцию сравнения (любая функция, которая принимает два значения и возвращает true, если первая строго меньше другой)

// sort in descending order, by passing in a custom comparer which uses greater than instead of less than
bool greater(int lhs, int rhs) { return lhs > rhs; }
std::sort(container.begin(), container.end(), greater);

Конечно, мы могли бы сортировать только первые пять элементов вектора:

std::sort(container.begin(), container.begin()+5);

Функции begin() и end() - это просто удобные функции для получения итераторов из контейнера. Мы не должны использовать их напрямую.

Другим приятным трюком является то, что потоки тоже могут быть обобщены на итераторы. Поэтому давайте прочитаем все целые числа из файла и скопируем их в массив (массивы - это простые типы C, конечно, поэтому они не являются надлежащими контейнерами и не имеют итераторов, но указатели работают нормально)

int arr[1024];
std::ifstream file("something.txt");
// (note, this assumes <= 1024 integers are read)
std::copy(std::istream_iterator<int>(file) // create an iterator pointing to the current position in the file stream
        , std::istream_iterator<int>() // and our "end" iterator. When we reach the end of the stream, testing the two iterators for equality will yield true, and so the operation will halt
        , arr);

Уникальная вещь о STL заключается в том, насколько она гибкая и расширяемая. Он взаимодействует чисто с C-кодом (указатели являются законными итераторами), его можно просто и легко расширять (вы можете написать свои собственные типы итераторов, если хотите. Большинство алгоритмов принимают пользовательские предикаты сравнения, как показано выше, и вы можете определить свои собственные контейнеры, т.е. каждый из трех столпов STL можно переопределить или расширить, поэтому STL можно назвать стратегией дизайна, а не любым. Вы можете написать код STL, даже если вы используете ваши собственные контейнеры, итераторы и алгоритмы. И поскольку каждый из этих трех столпов чисто отделен от других, их можно поменять местами намного легче, чем на большинстве других языков, где эти три обязанности смешиваются и разделяются одними и теми же классами. Алгоритм не знает, в каком контейнере хранится последовательность, в которой он работает. Он знает только, что итераторы, которые были переданы, могут быть разыменованы, чтобы получить доступ к самим данным. Контейнер не должен поддерживать все стандартные алгоритмы. Он просто должен иметь возможность создавать пару итераторов, а затем все функции предоставляются бесплатно.

Сравните это, скажем, с Java, где каждый класс коллекции должен реализовать свой собственный поиск, свой собственный вид, свое собственное. В С++ нам нужна только одна реализация find(). Требуется два итератора и ценность, которую нужно искать, и она пересекает последовательность, ища значение. Таким образом, он работает с любым типом контейнера, даже теми, которые я сам определяю.

Еще одна замечательная особенность STL заключается в том, что в ее использовании имеется буквально нулевая потеря производительности. Шаблоны С++ заменяются во время компиляции, приносящий код, который можно оптимизировать так же агрессивно, как если бы у вас было закодированное вручную все в C. Вышеуказанная функция сортировки потеряла бы некоторую производительность, потому что я передаю ей указатель функции как мой пользовательский сопоставитель, которые обычно не могут быть встроены, но это может быть исправлено, если мы определяем его как таковое:

struct greater {
    bool operator()(int lhs, int rhs) { return lhs > rhs; }
};
std::sort(container.begin(), container.end(), greater());

Теперь мы больше не передаем указатель на функцию, а объект. И функции-члены (такие как operator()) могут быть встроены. Таким образом, эта функция сортировки будет столь же эффективной, как и все, что вы могли бы передать в C.

И снова, даже не нужно добавлять какую-либо сложность в функцию сортировки. Фактически, сортировка имеет ровно две перегрузки. Тот, который выполняет функцию сравнения, и тот, который этого не делает.

Функция сортировки не должна знать, передается ли ей указатель на функцию или объект. Пока синтаксис "X (a, b)" действителен, где X - это значение, которое оно было передано как сравнивающее, а a, b - элементы для сравнения, будет работать одна и та же реализация функции сортировки. И поскольку мой объект greater перегружает operator(), этот синтаксис действителен как для этого объекта, так и для указателя функции, который мы передали ранее. STL-код получает множество функций бесплатно, используя такие трюки. Такая же реализация функции работает с очень разными типами аргументов из-за того, как работают шаблоны С++.

Ответ 2

STL - это стандартная библиотека шаблонов. Это подмножество стандартной библиотеки С++.

STL предоставляет общие реализации полезных алгоритмов и контейнеров.

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

Ответ 3

Стандартная библиотека шаблонов была библиотекой, написанной на С++ до стандартизации С++. Это включало классные вещи, такие как алгоритмы сортировки и контейнеры (и итераторы, с помощью которых можно использовать эти функции).

Части Стандартная библиотека С++, стандартизованная в 1998 году, основывались на частях STL; он с тех пор эволюционировал (через стандарт 2003 года, и особенно теперь с С++ 0x).

  • Стандартная библиотека С++ реализуется различными поставщиками компиляторов (и их друзьями) и поставляется с вашей любимой инструментальной цепочкой.
  • Это то, что вы на самом деле можете использовать: STL уже устарел.

Обратите внимание, что многие программисты (в том числе некоторые плодовитые авторы книг) по-прежнему используют термин "STL" по привычке для обращения к стандартной библиотеке С++ (или к тем частям, которые первоначально были основаны на STL), хотя это неверно. Пока вы знаете о техническом различии, вы должны быть в порядке.

Надеюсь, что это поможет.

Ответ 4

Реализации стандартной библиотеки шаблонов бесполезны для вас, если вы не программист на С++. Однако идеи превосходят любой язык программирования.

Это библиотека структур данных (например, карт, списков, векторов и т.д.). Он включает итераторы для абстрактного перемещения этих структур данных и алгоритмов для их работы. Другие языки также используют эти идеи, поэтому, если вы изучите их на одном языке, они будут знакомы с другими.

Ответ 5

STL - это стандартная библиотека шаблонов. Это библиотека функций и классов, которые вы можете использовать. Он имеет множество основных алгоритмов и структур данных базовой информатики. Если вы планируете остаться на С++, вам следует планировать изучение этой или другой библиотеки ресурсов.

Код используется многими людьми по всему миру, поэтому вам может быть удобно, что код хорошо протестирован и хорошо известен.

Ответ 6

C++ STL - это набор контейнерных классов и алгоритмов, которые мы обычно используем в программировании, особенно в конкурентном программировании, они экономят много нашего времени, потому что мы можем использовать готовые возможности C++ STL. STL обозначает стандартную библиотеку шаблонов. Он называется шаблоном, потому что вы должны указать классу контейнера, с каким типом данных он будет работать, т.е. вы назначаете тип данных шаблону класса контейнера. Если вы хотите узнать больше о C++ STL, я бы порекомендовал это полное руководство по C++ STL

Полное руководство C++ STL

Ответ 7

Это библиотека, которая упрощает некоторые вещи, такие как манипуляции с строкой, векторы, связанные списки и т.д. STL избавит вас от необходимости писать код более низкого уровня и позволит вам больше сосредоточиться на вашем коде приложения.