Your SlideShare is downloading. ×

Сергей Жгировский — С++11/14 в STL

965

Published on

Речь пойдёт о расширении библиотеки STL в стандарте С++11/C++14. Мы поговорим о новых контейнерах, алгоритмах, многопоточности, умных указателях и других полезных вещах, которые появились в новом …

Речь пойдёт о расширении библиотеки STL в стандарте С++11/C++14. Мы поговорим о новых контейнерах, алгоритмах, многопоточности, умных указателях и других полезных вещах, которые появились в новом стандарте и активно используются в Яндексе.

Published in: Technology
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
965
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
6
Comments
0
Likes
3
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. карты C++11/14: Хеш-таблицы; Умные указатели; Многопоточность. Жгировский Сергей Яндекс.Карты С++ party, Минск
  • 2. Хеш-таблицы 3
  • 3. Предыдущие реализации • hash_set, hash_map и др. - расширение языка; • различные реализации, интерфейсы; ! • VS: stdext::hash_set;! • GCC: __gnu_cxx::hash_set; ! • C 2007: std::tr1::unordered_set, -map, ... 4
  • 4. C++11 std::unordered_set;! std::unordered_map;! std::unordered_multiset;! std::unordered_multimap. 5 std::set;! std::map;! std::multiset;! std::multimap.
  • 5. Концептуальноe представление 6 Хеш-таблица (unordered_set) Красно-чёрное дерево (set)
  • 6. O(1)! ! O(1)! O(1) ! ————— O(1) … O(n)! ! O(1) … O(n)! O(1) … O(n)! ————— Алгоритмическая сложность 7 Хеш-таблица Красно-чёрное дерево O(log n)! ! O(log n)! O(log n)! O(log n) insert! ! erase! find! lower,upper_bound Амортизационная оценка
  • 7. rehash • unordered_*::rehash(size_t bucket_count);! • Происходит каждый раз при «переполнении» контейнера 
 (заполненность = size() / bucket_count() ); • nextprime(2 * bucket_count()); // GCC only • O(n) … O(n2). 8
  • 8. Использование 9 template<! class Key,! class Hash = std::hash<Key>,! class KeyEqual = std::equal_to<Key>,! class Allocator = std::allocator<Key>! > class unordered_set;
  • 9. std::hash • основных типов; • указателей; • std::string, wstring, u16string, u32string;! • std::unique_ptr, std::shared_ptr;! • std::error_code, std::thread::id;! • std::bitset, std::vector<bool>. 10 В библиотеке присутствует специализация для:
  • 10. std::hash Для всего остального std::hash не определён: 11 • std::vector<T>, list, deque, array, set, map, и все остальные контейнеры; • std::pair<T1, T2>, std::tuple<...>.
  • 11. Пользовательские типы class A {! public:! bool operator == (const A& rhs) const;! friend class std::hash<A>;! ! private:! int x_;! std::string y_;! }; 12
  • 12. Пользовательские типы namespace std {! template<>! struct hash<A> {! size_t operator()(const A& rhs) const {! size_t val = 0;! val += hash<int>()(rhs.x_) * 31;! val += hash<string>()(rhs.y_) * 59;! // boost::hash_combine! return val;! }! };! } 13
  • 13. Умные указатели 14
  • 14. Зачем? const A* a = new A;! ! delete a; ! throw std::exception();!
  • 15. Базовая реализация 16 template <typename T>! class smart_ptr! {! T* ptr;! public:! explicit smart_ptr(T* p) : ptr(p) {}! ~smart_ptr() { delete ptr; }! };!
  • 16. Прошлое std::auto_ptr! deprecated в С++11 ! 17 ! Конструктор копирования: auto_ptr(auto_ptr& other)! ! std::auto_ptr<int> x = y; // y пуст
  • 17. Настоящее 18 #include <memory>! ! std::unique_ptr! std::shared_ptr! std::weak_ptr
  • 18. std::unique_ptr Замена std::auto_ptr;! ! auto x = std::unique_ptr<A>(new A);! auto y = x; // теперь это не компилируется auto z = std::move(x); // зато работает перемещение 19
  • 19. Функциональность • можно использовать в контейнерах; • работает с неполными типами; • поддерживает указатели на массивы; • пользовательские «удаляторы»; • поддерживает полиморфизм; 20
  • 20. Неполные типы class A {! public:! // публичный интерфейс! ! private:! // все внутренности спрятаны! class AImpl;! smart_ptr<AImpl> impl_;! }; 21
  • 21. Неполные типы class A;! A* a = f();! delete a; // undefined behaviour 22
  • 22. Пользовательские «удаляторы» template<! class T,! class Deleter = std::default_delete<T>! > class unique_ptr; 23
  • 23. Пользовательские «удаляторы» const Resource* resource = ! acquireResource();! ! std::unique_ptr<Resource> up(! ! resource,! ! releaseResource);! // ресурс будет удалён, когда ‘up’ выйдет! // из области действия либо в случае любых! исключений 24
  • 24. Полиморфизм std::unique_ptr<Base> up(new Derived);! ! 25 ! std::unique_ptr<Base> b;! std::unique_ptr<Derived> d(new Derived);! b = std::move(d);
  • 25. std::make_unique (C++14!) std::unique_ptr<! TransactionalDataSourceContextBase! > up(new ! TransactionalDataSourceContextBase(1,2,3)); 26
  • 26. std::make_unique (C++14!) f(unique_ptr<A>(new A(1,2,3)),! unique_ptr<B>(new B(1,2)));! ! auto up = std::make_unique<A>(1,2,3); 27
  • 27. std::shared_ptr auto x = std::shared_ptr<A>(new A);! auto y = x; // можно копировать // A будет удалён, когда последний из владеющих им объектов будет удалён ! auto z = std::move(x); // перемещение также продолжает работать, если не хотим копировать. 28 разделяемое владение объектом;
  • 28. Концептуальное представление 29 ptr ref Object блок подсчёта ссылок shared_ptr ! ! !
  • 29. std::make_shared 30 ptr ref Object блок подсчёта ссылок shared_ptr ! ! ! Одно выделение памяти (помимо всего прочего) Exception safe «We know were you live» optimization
  • 30. Многопоточность 31
  • 31. Что нового std::thread;! std::async, std::future;! mutexes;! atomics;! conditional variables;! thread_local data. 32
  • 32. std::thread #include <thread>! void f();! ! struct Doer {! void operator()() const;! };! ! int main() {! std::thread th1(f); // сразу же начинает работать! std::thread th2(Doer{});! std::thread th3([]{ ... });! ! th1.join(); th2.join(); th3.join();! ! return 0;! } 33
  • 33. ! ! ! ! ! { ! std::thread th(...);! // деструктор:! join(); detach(); std::terminate(); // ?! } деструктор std::thread 34
  • 34. std::vector<std::future<int>> results;! for (int i=0; i<10; ++i)! results.push_back(std::async(heavy_computation));! ! for (auto& f : results)! std::cout << f.get() << std::endl; Асинхронные задачи 35
  • 35. std::launch::async! std::launch::deferred! ! Политика запуска 36 ! ! ! std::async(std::launch::async, heavy_computation);
  • 36. Деструктор std::future 37 void calculate_asynchronously() {! std::async(heavy_computation);! }
  • 37. Деструктор std::future 38 void calculate_asynchronously() {! std::async(std::launch::async, heavy_computation);! std::async(std::launch::async, heavy_computation2);! // не параллельно!! }
  • 38. Не оставляйте задачи без присмотра 39 void calculate_asynchronously() {! std::future<void> a = std::async(heavy_computation);! auto b = std::async(heavy_computation2);! a.get();! b.get();! }
  • 39. thread_local 40 template<typename Key, typename Value>! class SmallCachedStorage {! private:! thread_local std::unordered_map<Key, Value> cached_;! ! public:! Value calculate(const Key& key); // cached! };! boost::thread_specific_ptr<T>;!
  • 40. Спасибо за внимание!
  • 41. карты Жгировский Сергей ! Яндекс.Карты разработчик ! ixanezis@yandex-team.ru

×