programming.systems.cpp.07.stl (1119531), страница 2
Текст из файла (страница 2)
Ключевое слово typename используется при описаниипараметра-типа шаблона (наряду с ключевым словом class).Например,template <typename T>void f (T a) {...}2. Если используемое в шаблоне имя типа зависит отпараметров шаблона, необходимо использовать ключевоеслово typename. Например,template <class T>void f (vector <T> & v){vector <T> :: iterator i = begin ();// Err!typename vector <T> :: iterator i = begin(); //O.K....}16Пример шаблонной функции, использующей тип,вложенный в класс–параметр шаблонаstruct X {enum { e1, e2, e3 } g;struct inner {int i, j;void g ( ) { cout << “ggg\n”; }};inner c;};template < class T >void f ( typename T::inner t ) { t.g ( ); }int main ( ) {X x;x.g = X::e1;x.c.g ( );X::inner iii;iii.i = 7;f <X> ( iii );return 0;}17Пример шаблонной функции дляконтейнеров STLПоиск заданного элемента в контейнере, начиная споследнего (просмотр контейнера от конца к началу)обычно производится так:template < class C >typename C :: const_iterator find_last( const C & c, typename C :: value_type v ){typename C :: const_iterator p = c.end ( );while (p != c.begin ( ) )if ( * -- p == v )return p;return c.end ( );}18Контейнер vectortemplate < class T , class A = allocator < T > > сlass vector {.......public:// Типы – typedef …...
- см. выше// Итераторы …….. - см. выше//// Доступ к элементам//reference operator [ ] (size_type n); // доступ без проверки диапазонаconst_reference operator [ ] (size_type n) const;reference at (size_type n); // доступ с проверкой диапазона (если индекс// выходит за пределы диапазона, возбуждается исключение out_of_range)const_reference at (size_type n) const;reference front ( ); // первый элемент вектораconst_reference front ( ) const;reference back (); // последний элемент вектораconst_reference back ( ) const;19Контейнер vector// Конструкторы, деструктор, operator=//explicit vector (const A&=A()); //создается вектор нулевой длиныexplicit vector (size_type n; const T& value = T(); const A& = A());// создается вектор из n элементов со значением value// (или с "нулями" типа T, если второй параметр отсутствует;// в этом случае конструктор умолчания в классе Т обязателен)template <class I> vector (I first, I last, const A& = A());// инициализация вектора копированием элементов из [first, last),// I - итератор для чтенияvector (const vector < T, A > & obj ); // конструктор копированияvector& operator = (const vector < T, A > & obj );~vector();20Контейнер vector//Некоторые функции-члены класса vector//iterator erase (iterator i ); // удаляет элемент, на который указывает данный// итератор.
Возвращает итератор элемента, следующего за удаленным.iterator erase (iterator st, iterator fin); // удалению подлежат все элементы// между st и fin, но fin не удаляется. Возвращает fin.Iterator insert ( iterator i , const Т& value = T()); // вставка некоторого// значения value перед i. Возвращает итератор вставленного элемента).void insert (iterator i , size_type n, const T&value); // вставка n копий// элементов со значением value перед i.void push_back ( const T&value ) ; // добавляет элемент в конец вектораvoid pop_back () ; // удаляет последний элемент (не возвращает значение!)size_type size() const; // выдает количество элементов вектораbool empty () const; // возвращает истину, если вызывающий вектор пустvoid clear(); //удаляет все элементы вектора....}21Контейнер listtemplate < class T , class A = allocator < T > > сlass list {...........public:// Типы//……..// Итераторы//……..//// Доступ к элементам//reference front (); // первый элемент спискаconst_reference front () const;reference back (); // последний элемент спискаconst_reference back () const;22Контейнер list// Конструкторы, деструктор, operator=//explicit list (const A& = A()); // создается список нулевой длиныexplicit list (size_type n; const T& value = T(); const A& = A());// создается список из n элементов со значением value// (или с "нулями" типа Т, если второй параметр отсутствуетtemplate <class I> list (I first, I last, const A& = A());// инициализация списка копированием элементов из [first, last),// I - итератор для чтенияlist (const list < T, A > & obj ); // конструктор копированияlist& operator = (const list < T, A > & obj );~list();23Контейнер list//Некоторые функции-члены класса list//iterator erase (iterator i ); // удаляет элемент, на который указывает данный// итератор.
Возвращает итератор элемента, следующего за удаленным.iterator erase (iterator st, iterator fin); // удалению подлежат все элементы// между st и fin, но fin не удаляется. Возвращает fin.Iterator insert ( iterator i , const Т& value = T()); // вставка некоторого// значения value перед i. Возвращает итератор вставленного элемента).void insert (iterator i , size_type n, const T&value); // вставка n копий// элементов со значением value перед i.void push_back ( const T&value ) ; // добавляет элемент в конец спискаvoid push_front ( const T&value ) ; // добавляет элемент в начало спискаvoid pop_back ( ) ; // удаляет последний элемент (не возвращает значение!)void pop_front ( ) ; // удаляет первый элемент спискаsize_type size( ) const; // выдает количество элементов спискаbool empty ( ) const; // возвращает истину, если вызывающий список пустvoid clear( ); // удаляет все элементы списка……….24}Пример использования STLФункция, формирующая по заданному вектору целых чисел списокиз элементов вектора с четными значениями ираспечатывающая его.# include < iostream ># include < vector ># include < list >using namespace std;void g (vector <int> & v, list <int> & lst) {int i;for (i = 0; i < v.size( ); i++)if ( ! ( v[ i ] % 2 ) )lst.push_back( v[ i ] );list < int > :: const_iterator p = lst.begin ();while ( p != lst.end ( ) ) {cout << *p << endl;p++;}}25Достоинства STL - подхода•Каждый контейнер обеспечивает стандартный интерфейс в виденабора операций, так что один контейнер может использоватьсявместо другого, причем это не влечет существенного изменения кода.•Дополнительная общность использования обеспечивается черезстандартные итераторы.•Каждый контейнер связан с распределителем памяти - аллокатором,который можно переопределить с тем, чтобы реализоватьсобственный механизм распределения памяти.•Для каждого контейнера можно определить дополнительныеитераторы и интерфейсы, что позволит оптимальным образомнастроить его для решения конкретной задачи.•Контейнеры по определению однородны, т.е.
должны содержатьэлементы одного типа, но возможно создание разнородныхконтейнеров как контейнеров указателей на общий базовый класс.•Алгоритмы, входящие в состав STL, предназначены для работы ссодержимым контейнеров. Все алгоритмы представляют собойшаблонные функции, следовательно, их можно использовать дляработы с любым контейнером.26.