24
Лекция 1. Стандартная библиотека Контейнеры Valery Lesin. C++ In-Depth, 2014

C++ 2: Библиотека STL. Контейнеры

Embed Size (px)

DESCRIPTION

- Гарантии и требования к элементам - Контейнеры и адаптеры

Citation preview

Page 1: C++ 2: Библиотека STL. Контейнеры

Лекция 1. Стандартная

библиотека

Контейнеры

Valery Lesin. C++ In-Depth, 2014

Page 2: C++ 2: Библиотека STL. Контейнеры

Стандартная библиотека

• Минимальный полный набор возможностей для обеспечения базовых потребностейю.

• Если что-то содержит, должна реализовывать лучшим образом (стать стандартом де-факто).

• Алгоритмически эффективна.

• Расширяема (может использовать как стандартные, так и пользовательские типы).

Valery Lesin. C++ In-Depth, 2014

Page 3: C++ 2: Библиотека STL. Контейнеры

Состав стандартной библиотеки• Включает в себя CRT (C Run Time Library) и

STL (Standard Template Library)

• Содержит

– контейнеры: vector, list, map, unordered_set, …

– утилиты: пары, аллокаторы, …

– итераторы

– алгоритмы: for_each, sort, lower_bound, …

– диагностика: assert, exception, …

– строки: string, wstring

– ввод/вывод: потоки cout, cin; printf, …

Valery Lesin. C++ In-Depth, 2014

Page 4: C++ 2: Библиотека STL. Контейнеры

Состав стандартной библиотеки (2)

• Содержит (продолжение):

– локализацию

– поддержку языка: numeric_limits, typeinfo, new/delete

– числовые операции: complex, <cmath>

• Для хидера <name.h> из CRT есть хидер<cname> с теми же объявлениями в пространстве имен std

• Используйте только стандартные хидерадля объявления стандартных типов и функций

Valery Lesin. C++ In-Depth, 2014

Page 5: C++ 2: Библиотека STL. Контейнеры

Контейнеры STL

• Реализуют стандартные операции с соответствующими именами и смыслом.

• Однородны – все хранимые объекты одного типа. Но могут хранить указатели (желательно умные) на полиморфные.

• Требуют минимум от хранимого типа.

• Универсально итерируемы.

• Можно настроить (аллокаторы, компараторы).

Valery Lesin. C++ In-Depth, 2014

Page 6: C++ 2: Библиотека STL. Контейнеры

Типы контейнеров

• Списочные: array, vector, list, deque, forward_list

• Ассоциативные: map, set, multiset,multimap

• Unordered: unordered_map,

unordered_multiset, …

• Адапторы: stack, queue, priority_queue

• «Почти» контейнеры: bitset, string, …

Valery Lesin. C++ In-Depth, 2014

Page 7: C++ 2: Библиотека STL. Контейнеры

Контейнер vector

Valery Lesin. C++ In-Depth, 2014

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

template<class T, class Allocator = std::allocator<T>>

class vector

{

typedef typename T value_type;

typedef Allocator allocator_type;

typedef typename Allocator::size_type size_type;

typedef typename Allocator::difference_type difference_type;

typedef typename Allocator::pointer pointer;

typedef typename Allocator::const_pointer const_pointer;

typedef typename Allocator::reference reference;

typedef typename Allocator::const_reference const_reference;

typedef impl-defined iterator;

typedef impl-defined const_iterator;

typedef reverse_iterator<iterator> reverse_iterator;

typedef reverse_iterator<const_iterator> const_reverse_iterator;

// ...

};

Page 8: C++ 2: Библиотека STL. Контейнеры

Valery Lesin. C++ In-Depth, 2014

Итераторы1.

2.

3.

4.

5.

6.

7.

8.

9.

10.

11.

12.

13.

14.

15.

16.

17.

18.

19.

20.

21.

22.

23.

template<class T, class Allocator = std::allocator<T>>

class vector

{

// ...

iterator begin();

const_iterator begin() const;

iterator end();

const_iterator end() const;

reverse_iterator rbegin();

const_reverse_iterator rbegin() const;

reverse_iterator rend();

const_reverse_iterator rend() const;

const_iterator cbegin() const;

const_iterator cend () const;

const_reverse_iterator crbegin() const;

const_reverse_iterator crend () const;

// ...

};

Page 9: C++ 2: Библиотека STL. Контейнеры

Итераторы

• Типы итераторов: Output; Input, Forward,

Bidirectional, RandomAccess

Valery Lesin. C++ In-Depth, 2014

Item 0 Item 1 Item 2 Item 3

end

cend

begin

cbegin

it

reverse it

1.

2.

&(*reverse_it) != &(*(revese_it.base()));

&(*reverse_it) == &(*(std::prev(revese_it).base()));

Page 10: C++ 2: Библиотека STL. Контейнеры

По вектору в обратном направлении

Valery Lesin. C++ In-Depth, 2014

1.

2.

3.

4.

5.

6.

7.

8.

9.

10.

11.

12.

13.

14.

15.

16.

17.

18.

19.

20.

// forward

for (size_t i = 0; i < v.size(); ++i)

cout << v[i] << endl;

// naive backward (hmmm, with suprises)

for (size_t i = v.size() - 1; i >= 0; ++i)

cout << v[i] << endl;

// correct

for (vector<int>::const_reverse_iterator it = v.rbegin();

it != v.rend(); ++it)

cout << *it << endl;

// correct and tiny

for (auto it = v.rbegin(); it != v.rend(); ++it)

cout << *it << endl;

// range-based for

for (auto item : reverse(v))

cout << item << endl;

Page 11: C++ 2: Библиотека STL. Контейнеры

Как устроен вектор?

• Вектор – динамический массив.

• При нехватке места увеличивается ~ в 2 раза

• Трудоемкость вставки в конец (!) –амортизированная O(1)

Valery Lesin. C++ In-Depth, 2014

Size

Capacity

1.

2.

3.

4.

5.

6.

7.

8.

9.

10.

11.

bool empty() const;

size_type size () const;

void resize(size_type size, T val = T());

size_type capacity() const;

void reserve (size_type size);

void clear ();

void shrink_to_fit();

iterator erase (const_iterator where);

Page 12: C++ 2: Библиотека STL. Контейнеры

Вставка и удаление из вектора

• Функция remove и remove_if ничего не

удаляют, а лишь переносят в конец.

Valery Lesin. C++ In-Depth, 2014

1.

2.

3.

4.

5.

6.

7.

8.

9.

10.

11.

12.

13.

// could be const_iterator since C++11

vector<T>::iterator from, to, where;

// random place

v.insert(where, val);

// usual erase

v.erase(from, to);

v.erase(where);

// erase items with value with 'remove' function

// or use 'remove_if' for predicate usage

v.erase(v.begin(), remove(v.begin(), v.end(), 42));

Page 13: C++ 2: Библиотека STL. Контейнеры

Вектор. Концевые элементы и индекс

• Вектор позволяет эффективно вставлять и удалять элементы с конца. Но (!) не сначала.

Valery Lesin. C++ In-Depth, 2014

1.

2.

3.

4.

5.

6.

7.

8.

9.

10.

11.

12.

13.

14.

15.

16.

17.

18.

void push_back(T const& value);

void push_back(T && value);

template< class... Args >

void emplace_back( Args&&... args );

void pop_back();

reference back();

const_reference back() const;

reference front();

const_reference front() const

pointer data(); // and const

reference operator[](size_type index);

reference at(size_type index);

Page 14: C++ 2: Библиотека STL. Контейнеры

Конструирование вектора

• Конструктор по умолчанию, копирования,

move-конструктор

• А также:

Valery Lesin. C++ In-Depth, 2014

1.

2.

3.

4.

5.

6.

7.

8.

vector<T> v0(from, to);

vector<T> v1(num, value);

// reassign already constructed vector

v0.assign(from, to);

// initializer list (since C++11)

vector<int> v2 = {1, 42, 10, 20};

Page 15: C++ 2: Библиотека STL. Контейнеры

Контейнер sdt::list

• Двунаправленный список

• Вставка, удаление из любого места О(1)

• Нет RandomAccess итератора, только

Bidirectional

• Полезны splice, sort

• В отличие от вектора: pop_front, push_front

Valery Lesin. C++ In-Depth, 2014

1.

2.

template<class T, class Alloc = std::allocator<T>>

class list;

Page 16: C++ 2: Библиотека STL. Контейнеры

Контейнер std::deque

• Есть RandomAccess итератор (возможно,

несколько менее эффективно, чем в

векторе)

• Позволяет вставлять/удалять в начало и

конец за O(1) (но не в произвольное место)

• Часто реализуется через вектор векторов

Valery Lesin. C++ In-Depth, 2014

Page 17: C++ 2: Библиотека STL. Контейнеры

Адаптеры

• std::stack: push, pop, top

• std::queue: push, pop, front, back

• std::priority_queue: push, pop, top,

constructor

Valery Lesin. C++ In-Depth, 2014

1.

2.

3.

4.

template<class T,

class Container = vector<T>,

class Pr = less<typename Container::value_type>>

class priority_queue;

Page 18: C++ 2: Библиотека STL. Контейнеры

Ассоциативные контейнеры

• Наиболее популярный – std::map

Valery Lesin. C++ In-Depth, 2014

1.

2.

3.

4.

5.

6.

7.

8.

9.

10.

11.

12.

13.

14.

template<

class Key,

class Value,

class Predicate = less<Key>,

class Alloc = allocator<pair<const Key, Value>>>

class map

{// usually, some balanced tree (e.g. red-black)

public:

typedef Key key_type;

typedef Value mapped_type;

typedef pair<const Key, Value> value_type;

typedef Predicate key_compare;

// ...

};

Page 19: C++ 2: Библиотека STL. Контейнеры

Итерирование map

• Итератор разыменовывается в пару. Ключ –

first, значение – second.

Valery Lesin. C++ In-Depth, 2014

1.

2.

3.

4.

5.

6.

7.

8.

map<string, size_t> marks;

for (auto it = marks.begin(); it != marks.end(); ++it)

cout << it->first << " " << it->second << endl;

//...

it->second = 5; // ok

it->first = "Vasya"; // nope, cannot change key

Page 20: C++ 2: Библиотека STL. Контейнеры

Поиск и вставка в map

Valery Lesin. C++ In-Depth, 2014

1.

2.

3.

4.

5.

6.

7.

8.

9.

10.

11.

12.

13.

14.

15.

16.

17.

18.

19.

typedef std::map<string, size_t> map_t;

typedef map_t::iterator iterator;

map_t m;

// simple insert

auto it = m.find(str);

if (it != n.end())

return ...;

pair<iterator, bool> p =

m.insert(make_pair(str, 5));

// with 'hint'

auto it = m.lower_bound(str);

if (it != m.end() && it->second == str)

return ...;

m.insert(it, make_pair(str, 5));

Page 21: C++ 2: Библиотека STL. Контейнеры

Индексирование

• Если элемента не было в map – добавит

• Если был – оператора вернет ссылку и

произойдет замена текущего значения (в

отличие от insert)

• Оператор [] всегда неконстантный. Есть

только у map, нет у set, multiset, multimap.

Valery Lesin. C++ In-Depth, 2014

1.

2.

3.

4.

5.

6.

typedef std::map<string, size_t> map_t;

typedef map_t::iterator iterator;

map_t m;

m[str] = 5;

Page 22: C++ 2: Библиотека STL. Контейнеры

Удаление из map (set)

Valery Lesin. C++ In-Depth, 2014

1.

2.

3.

4.

5.

6.

7.

8.

9.

10.

11.

m.erase(key);

m.erase(from, to);

// with predicate

for (auto it = m.begin(); it != m.end(); ++it)

{

if (predicate(*it))

m.erase(it++);

else

++it;

}

Page 23: C++ 2: Библиотека STL. Контейнеры

Другие ассоциативные контейнеры

• std::set – содержит только ключи

• std::multimap, std::multiset – ключи могут повторяться

• std::unordered_map/set

– используют вычисление хэшей и предикат равенства вместо предиката порядка

– вставка, удаление, поиск – амортизированная O(1)

– Требуют больше памяти, чем обычные map/set

– Есть более быстрые реализации: Google sparse/dense hash map, MCT hash map

Valery Lesin. C++ In-Depth, 2014

Page 24: C++ 2: Библиотека STL. Контейнеры

Спасибо за внимание!

Вопросы?

Valery Lesin. C++ In-Depth, 2014