Очень краткий курс STL. Часть I

Очень краткий курс STL (Standart Templay Library) – т.е. библиотекой шаблонов.

Что такое шаблон.

Шаблон эта некая абстрактная обертка над любым типом данных. Как, например, круг – бывает геометрическая фигура, а бывает и спасательный. Дурацкое сравнение но ничего лучшего в голову не лезет.
STL ясен пень, написан на C++, синтаксис объявления шаблонов – тип шаблона и в угловых скобках (через запятую если не один) тип данных, например: vector<int> array_int или map<string,int> domainPR.

Опишу наиболее популярные шаблоны.
vector (а также остальные шаблоны на его примере). Это вектор (гы-гы однострочный массив, а вы как думали), да массивы мы и int array[100] сделаем – скажите вы. Конечно, - отвечу – но vector – безразмерный массив – и сам себе распределяет память. Кстати о распределение памяти и о allocator’ах – можно почитать в более профессиональной (но нудной) литературе.

И так синтаксис.
vector<int> array; //Мы объявили вектор с типом данных int
vector<double> array2; //Догадайтесь сами
vector<MyClass> array3;//Ага-ага в качестве типа данных можно использовать классы и структуры

Теперь как использовать сие(это в общем аналогично и для других-многих шаблонов).
Узнать количество элементов array.size()
Обратиться к элементу n – array[n] – конечно, просто перекрыт оператор [] (да поможет вам C++). Кстати будьте осторожны с оператором [], он запросто может вызвать ошибку(exception) при обращении вне диапазона данных, даже как вам кажется при создании, например для пустого вектора array[0] = 5 – будет ошибка если вектор не имеет одного значения.

Аналогично, но для гурманов - array.begin()+n.
Собственно begin() и end() это функции итераторы – begin() –указывает на первый элемент, а end() на следующий после последнего, обратите внимание – после последнего, а не на последний!.

Итераторы – это что-то типа указателей на элемент в шаблоне. Он объявляется как шаблон::iterator, например для вектора из int –
vector::iterator.

Поэтому первый совет – typedef'ите всегда и везде, особенно если ваш шаблон использует вложенные шаблоны или классы. Все будет проще для понимания и синтаксиса. Например:
typedef vector<int> IntArray;
IntArray array;
for(IntArray::iterator i=array.begin();i<array.end();i++)
printf(“%d\n”,*i);
Данный пример распечатывает элементы int'ного вектора. Кстати для тех кто в танке – итератор это еще и указатель на данные шаблона.
А теперь тот-же пример, но без typedef.
vector<int> array;
for(vector<int>::iterator i=array.begin();i<array.end();i++)
printf(“%d\n”,*i);
А теперь представьте, что у вас вектор векторов из списка – конструкция будет зверская.
Совет – для перебора в цикле лучше использовать не оператор <, а оператор i!=array.end(), т.к. оператор сравнения работает только на списочных шаблонов, а допустим для map'а – нет, а не равно работает и там и тут.

Как заполнить вектор готовыми значениями, допустим из int-массива –
int data[11] = {1,2,3,4,5,6,7,8,9,10,12};
vector<int,allocator<int> > array(data+0, data+11);
+11 – это указатель на конец массива, а как смещаться указывает allocator. Можно было также написать array(data+1,data+3) – создание вектора из двух значений – 2 и 3.
Поместить данные в конец – array.push_back(5);

Удалить данные – array.erase( vector<>::iterator), вот – допустим у вас int'овый индекс заполненный - 1,2,3,4,5 – то скажем удалить значение под 2 индексом (значение 3) – можно так array.erase( array.begin()+2).

Алгоритмы (algorithm)
Это набор процедур для различных шаблонов, которые облегчают жизнь. Различные алгоритмы – требует разный набор перегруженных операторов для шаблона, например для алгоритма сортировки (sort) необходимы операторы больше (или меньше) и не равно(или равно – не помню, но надеюсь меня поняли).

Алгоритм поиска (find)
Синтаксис итератор значение = find(начальный итератор, конечный итератор, значение), например для нашего многострадального вектора = vector<int>::iterator i=find(array.begin(),array.end(),5) – ищем число 5. Возвращает либо итератор на первый элемент с таким значеним, либо в случае неудачи итератор end(). Для поиска (скажем со второй позиции) может написать find(array.begin()+1,array.end(),5). Надеюсь как узнать под каким индексом нашелся найденный элемент у вас не составит? Итить – это просто i-array.begin()!

Алгоритм сортировки(sort)
Синтаксис
sort (array.begin(), array.end(), greater() ); // вместо greater можно писать not_equal_to ,Less,greater_equal и много еще чего, полный список в function – функции над шаблонами.

Алгоритм заполнения(generate)
Синтаксис generate(array.begin(),array.end(), функция_возвращающая_значение_того_же_типа);
Например int randomValue () { return randomInteger(100); } или int fillNumber(int a) { return a;}

Алгоритм вычислений (accumulate)
Сказать честно – самый (ИМХО) бестолковый. Требует модуль numeric.
Например подсчет суммы значений int sum = accumulate(array.begin(), array.end(), 0); - 0 это иницилизирующее значение, например можно выполнить с 1, тогда сумма будет на 1 единицу больше.
vector<int> array;
for(int i=1;i<10;i++) array.push_back(i);
int fact = accumulate(array.begin(), array.end(), 1, multiplies<int>());
А это значит, что accumulate можно запускать с функций (по умолчанию суммирования) – перечень всех функция – вы не поверите в модуле function. Например - plus<int>(), minus<int>() или divides<int>. И естественно функцию над шаблонами можно написать свою.

Алгоритм копирования (copy)
Синтаксис - copy(откуда,докуда,куда); - например copy(array.begin(),array.end(),array2.begin());
Естественно старые данные заместятся новыми, но если второй набор данных будет больше, то после конца первого набора, будут идти старые данные на своих прежних местах.

Про map и multimap уже написал тут.

Комментарии

ЛАК

НОРМ