Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 ·...

49
Одиннадцатая независимая научно-практическая конференция «Разработка ПО 20122 - 24 октября, Москва Михаил Матросов Повседневный С++ Align Technology [email protected] [email protected]

Transcript of Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 ·...

Page 1: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

Одиннадцатая независимая научно-практическая конференция «Разработка ПО 2015»

22 - 24 октября, Москва

Михаил Матросов

Повседневный С++

Align Technology [email protected]

[email protected]

Page 2: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 2

Page 3: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 3

С++17 С++11/14

С++98

С

High level

Expert level

Modern C++

Page 4: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

“Within C++ is a smaller, simpler, safer language struggling to get out”

Bjarne Stroustrup

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 4

Page 5: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

High level: Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры STL и boost Семантика перемещения λ-функции Классы и конструкторы Простые шаблоны

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 5

Expert level: Операторы new/delete, владеющие

указатели Пользовательские операции копирования

и перемещения Пользовательские деструкторы Закрытое, защищённое, ромбовидное,

виртуальное наследование Шаблонная магия, SFINAE Все функции языка Си, препроцессор «Голые» циклы

Классический слайд с телом и заголовком

Page 6: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 6

bool doCompare(const Bakery* oldBakery, const Bakery* newBakery) { if (!oldBakery || !newBakery) { return false; } std::vector<Cookie> oldCookies; std::vector<Cookie> newCookies; std::vector<std::pair<Cookie, int>> diff; collectCookies(*oldBakery, oldCookies); collectCookies(*newBakery, newCookies); std::sort(oldCookies.begin(), oldCookies.end(), compareCookies); std::sort(newCookies.begin(), newCookies.end(), compareCookies); auto oldIt = oldCookies.begin(); auto newIt = newCookies.begin(); while ((oldIt != oldCookies.end()) || (newIt != newCookies.end())) {

Page 7: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 7

bool doCompare(const Bakery* oldBakery, const Bakery* newBakery) { if (!oldBakery || !newBakery) { return false; } std::vector<Cookie> oldCookies; std::vector<Cookie> newCookies; std::vector<std::pair<Cookie, int>> diff; collectCookies(*oldBakery, oldCookies); collectCookies(*newBakery, newCookies); std::sort(oldCookies.begin(), oldCookies.end(), compareCookies); std::sort(newCookies.begin(), newCookies.end(), compareCookies); auto oldIt = oldCookies.begin(); auto newIt = newCookies.begin(); while ((oldIt != oldCookies.end()) || (newIt != newCookies.end())) { if (compareCookies(*oldIt, *newIt)) { diff.push_back(std::pair<Cookie, int>(*oldIt, 1)); ++oldIt; } else if (compareCookies(*newIt, *oldIt)) { diff.push_back(std::pair<Cookie, int>(*newIt, 2)); ++newIt; } else { ++oldIt; ++newIt; } } if (oldIt != oldCookies.end()) { for (; oldIt < oldCookies.end(); oldIt++) { diff.push_back(std::pair<Cookie, int>(*oldIt, 1)); } } if (newIt != newCookies.end()) { for (; newIt < newCookies.end(); newIt++) { diff.push_back(std::pair<Cookie, int>(*newIt, 2)); } } for (const auto& item : diff) { std::cout << "Bakery #" << item.second << " has a different cookie \"" << item.first.name << "\" (weight=" << item.first.weight << ", volume=" << item.first.volume << ", tastiness=" << item.first.tastiness << ")." << std::endl; } if (diff.size() > 0) return false; return true; }

bool doCompare(const Bakery& oldBakery, const Bakery& newBakery) { auto oldCookies = collectCookies(oldBakery); auto newCookies = collectCookies(newBakery); auto reportLost = [](const Cookie& cookie) { std::cout << "We've lost a friend: " << cookie << "." << std::endl; }; auto reportAppeared = [](const Cookie& cookie) { std::cout << "We got a new friend: " << cookie << "." << std::endl; }; boost::range::set_difference(oldCookies, newCookies, boost::make_function_output_iterator(reportLost)); boost::range::set_difference(newCookies, oldCookies, boost::make_function_output_iterator(reportAppeared)); return oldCookies == newCookies; }

Page 8: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 8

bool doCompare(const Bakery* oldBakery, const Bakery* newBakery) { if (!oldBakery || !newBakery) { return false; } std::vector<Cookie> oldCookies; std::vector<Cookie> newCookies; std::vector<std::pair<Cookie, int>> diff; collectCookies(*oldBakery, oldCookies); collectCookies(*newBakery, newCookies); // ...

Page 9: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 9

bool doCompare(const Bakery& oldBakery, const Bakery& newBakery) { std::vector<Cookie> oldCookies; std::vector<Cookie> newCookies; std::vector<std::pair<Cookie, int>> diff; collectCookies(oldBakery, oldCookies); collectCookies(newBakery, newCookies); // ...

Page 10: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 10

Page 11: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 11

// ... std::sort(oldCookies.begin(), oldCookies.end(), compareCookies); std::sort(newCookies.begin(), newCookies.end(), compareCookies); auto oldIt = oldCookies.begin(); auto newIt = newCookies.begin(); while ((oldIt != oldCookies.end()) || (newIt != newCookies.end())) { if (compareCookies(*oldIt, *newIt)) { diff.push_back(std::pair<Cookie, int>(*oldIt, 1)); ++oldIt; } else if (compareCookies(*newIt, *oldIt)) { // ...

Page 12: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 12

struct Cookie { double weight; double volume; std::string name; int tastiness; }; bool compareCookies(const Cookie& a, const Cookie& b) { if (a.tastiness != b.tastiness) return a.tastiness < b.tastiness; if (a.weight != b.weight) return a.weight < b.weight; if (a.volume != b.volume) return a.volume < b.volume; return a.name < b.name; }

Page 13: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 13

struct Cookie { double weight; double volume; std::string name; int tastiness; }; bool operator<(const Cookie& a, const Cookie& b) { if (a.tastiness != b.tastiness) return a.tastiness < b.tastiness; if (a.weight != b.weight) return a.weight < b.weight; if (a.volume != b.volume) return a.volume < b.volume; return a.name < b.name; }

Page 14: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 14

// ... std::sort(oldCookies.begin(), oldCookies.end(), compareCookies); std::sort(newCookies.begin(), newCookies.end(), compareCookies); auto oldIt = oldCookies.begin(); auto newIt = newCookies.begin(); while ((oldIt != oldCookies.end()) || (newIt != newCookies.end())) { if (compareCookies(*oldIt, *newIt)) { diff.push_back(std::pair<Cookie, int>(*oldIt, 1)); ++oldIt; } else if (compareCookies(*newIt, *oldIt)) { // ...

Page 15: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 15

// ... std::sort(oldCookies.begin(), oldCookies.end()); std::sort(newCookies.begin(), newCookies.end()); auto oldIt = oldCookies.begin(); auto newIt = newCookies.begin(); while ((oldIt != oldCookies.end()) || (newIt != newCookies.end())) { if (*oldIt < *newIt) { diff.push_back(std::pair<Cookie, int>(*oldIt, 1)); ++oldIt; } else if (*newIt < *oldIt) { // ...

Page 16: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 16

bool operator<(const Cookie& a, const Cookie& b) { if (a.tastiness != b.tastiness) return a.tastiness < b.tastiness; if (a.weight != b.weight) return a.weight < b.weight; if (a.volume != b.volume) return a.volume < b.volume; return a.name < b.name; }

Page 17: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 17

bool operator<(const Cookie& a, const Cookie& b) { return std::make_tuple(a.tastiness, a.weight, a.volume, a.name) < std::make_tuple(b.tastiness, b.weight, b.volume, b.name); }

Page 18: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 18

struct Cookie { double weight; double volume; std::string name; int tastiness; }; bool operator<(const Cookie& a, const Cookie& b) { return std::make_tuple(a.tastiness, a.weight, a.volume, a.name) < std::make_tuple(b.tastiness, b.weight, b.volume, b.name); }

Page 19: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 19

struct Cookie { double weight; double volume; std::string name; int tastiness; }; bool operator<(const Cookie& a, const Cookie& b) { return std::tie(a.tastiness, a.weight, a.volume, a.name) < std::tie(b.tastiness, b.weight, b.volume, b.name); }

Page 20: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 20

struct Cookie { double weight; double volume; std::string name; int tastiness; auto rank() const { return std::tie(tastiness, weight, volume, name); } bool operator<(const Cookie& rhs) const { return rank() < rhs.rank(); } };

Page 21: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 21

struct Cookie { double weight; double volume; std::string name; int tastiness; auto rank() const // -> std::tuple<double&, double&, std::string&, int&> { return std::tie(tastiness, weight, volume, name); } bool operator<(const Cookie& rhs) const { return rank() < rhs.rank(); } };

Page 22: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 22

Page 23: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

bool doCompare(const Bakery& oldBakery, const Bakery& newBakery) { std::vector<Cookie> oldCookies; std::vector<Cookie> newCookies; collectCookies(oldBakery, oldCookies); collectCookies(newBakery, newCookies); // ...

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 23

Page 24: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 24

void collectCookies(const Bakery& bakery, std::vector<Cookie>& o_cookies); bool doCompare(const Bakery& oldBakery, const Bakery& newBakery) { std::vector<Cookie> oldCookies; std::vector<Cookie> newCookies; collectCookies(oldBakery, oldCookies); collectCookies(newBakery, newCookies); // ...

Page 25: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 25

std::vector<Cookie> collectCookies(const Bakery& bakery); bool doCompare(const Bakery& oldBakery, const Bakery& newBakery) { std::vector<Cookie> oldCookies = collectCookies(oldBakery); std::vector<Cookie> newCookies = collectCookies(newBakery); // ...

Page 26: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 26

λ λ

= :

Page 27: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 27

std::vector<Cookie> collectCookies(const Bakery& bakery) { std::vector<Cookie> cookies; // ... // ... return cookies; } bool doCompare(const Bakery& oldBakery, const Bakery& newBakery) { std::vector<Cookie> oldCookies = collectCookies(oldBakery); std::vector<Cookie> newCookies = collectCookies(newBakery); std::sort(oldCookies.begin(), oldCookies.end()); std::sort(newCookies.begin(), newCookies.end()); // ...

Page 28: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 28

std::vector<Cookie> collectCookies(const Bakery& bakery) { std::vector<Cookie> cookies; // ... std::sort(cookies.begin(), cookies.end()); return cookies; } bool doCompare(const Bakery& oldBakery, const Bakery& newBakery) { std::vector<Cookie> oldCookies = collectCookies(oldBakery); std::vector<Cookie> newCookies = collectCookies(newBakery); // ...

Page 29: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 29

Page 30: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 30

std::vector<std::pair<Cookie, int>> diff; // ... if (*oldIt < *newIt) { diff.push_back(std::pair<Cookie, int>(*oldIt, 1)); ++oldIt; } else if (*newIt < *oldIt) { diff.push_back(std::pair<Cookie, int>(*newIt, 2)); ++newIt; }

Page 31: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 31

std::vector<std::pair<Cookie, int>> diff; // ... if (*oldIt < *newIt) { diff.push_back(std::make_pair(*oldIt, 1)); ++oldIt; } else if (*newIt < *oldIt) { diff.push_back(std::make_pair(*newIt, 2)); ++newIt; }

Page 32: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 32

std::vector<std::pair<Cookie, int>> diff; // ... if (*oldIt < *newIt) { diff.emplace_back(*oldIt, 1); ++oldIt; } else if (*newIt < *oldIt) { diff.emplace_back(*newIt, 2); ++newIt; }

Page 33: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

for (const auto& item : diff) // item is std::pair<Cookie, int> { std::cout << "Bakery #" << item.second << " has a different cookie \"" << item.first.name << "\" (weight=" << item.first.weight << ", volume=" << item.first.volume << ", tastiness=" << item.first.tastiness << ")." << std::endl; }

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 33

Page 34: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 34

for (const auto& item : diff) // item is std::pair<Cookie, int> { std::cout << "Bakery #" << item.second << " has a different cookie " << item.first << "." << std::endl; }

std::ostream& operator<<(std::ostream& stream, const Cookie& cookie) { return stream << "\"" << cookie.name << "\" (weight=" << cookie.weight << ", volume=" << cookie.volume << ", tastiness=" << cookie.tastiness << ")"; }

Page 35: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 35

if (diff.size() > 0) return false; return true;

Page 36: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 36

return diff.empty();

Page 37: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 37

Page 38: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 38

std::vector<std::pair<Cookie, int>> diff; auto oldIt = oldCookies.begin(); auto newIt = newCookies.begin(); while ((oldIt != oldCookies.end()) || (newIt != newCookies.end())) { if (*oldIt < *newIt) { diff.emplace_back(*oldIt, 1); ++oldIt; } else if (*newIt < *oldIt) { diff.emplace_back(*newIt, 2); ++newIt; } else { ++oldIt; ++newIt; } } for (; oldIt != oldCookies.end(); oldIt++) { diff.emplace_back(*oldIt, 1); } for (; newIt != newCookies.end(); newIt++) { diff.emplace_back(*newIt, 2); }

1 2 5 7 8 9

1 3 5 6 9

2 7 8 3 6

oldCookies

newCookies

diff

Ошибка. Должно быть &&

Page 39: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 39

Page 40: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 40

std::vector<Cookie> lostCookies; std::set_difference(oldCookies.begin(), oldCookies.end(), newCookies.begin(), newCookies.end(), std::back_inserter(lostCookies)); std::vector<Cookie> appearedCookies; std::set_difference(newCookies.begin(), newCookies.end(), oldCookies.begin(), oldCookies.end(), std::back_inserter(appearedCookies));

Page 41: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 41

std::vector<Cookie> lostCookies; boost::range::set_difference(oldCookies, newCookies, std::back_inserter(lostCookies)); std::vector<Cookie> appearedCookies; boost::range::set_difference(newCookies, oldCookies, std::back_inserter(appearedCookies));

Page 42: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 42

std::vector<Cookie> lostCookies; boost::range::set_difference(oldCookies, newCookies, std::back_inserter(lostCookies)); std::vector<Cookie> appearedCookies; boost::range::set_difference(newCookies, oldCookies, std::back_inserter(appearedCookies)); for (const auto& cookie : lostCookies) { std::cout << "We've lost a friend: " << cookie << "." << std::endl; } for (const auto& cookie : appearedCookies) { std::cout << "We got a new friend: " << cookie << "." << std::endl; }

Page 43: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 43

auto reportLost = [](const Cookie& cookie) { std::cout << "We've lost a friend: " << cookie << "." << std::endl; }; auto reportAppeared = [](const Cookie& cookie) { std::cout << "We got a new friend: " << cookie << "." << std::endl; }; boost::range::set_difference(oldCookies, newCookies, boost::make_function_output_iterator(reportLost)); boost::range::set_difference(newCookies, oldCookies, boost::make_function_output_iterator(reportAppeared));

Page 44: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 44

bool doCompare(const Bakery& oldBakery, const Bakery& newBakery) { std::vector<Cookie> oldCookies = collectCookies(oldBakery); std::vector<Cookie> newCookies = collectCookies(newBakery); auto reportLost = [](const Cookie& cookie) { std::cout << "We've lost a friend: " << cookie << "." << std::endl; }; auto reportAppeared = [](const Cookie& cookie) { std::cout << "We got a new friend: " << cookie << "." << std::endl; }; boost::range::set_difference(oldCookies, newCookies, boost::make_function_output_iterator(reportLost)); boost::range::set_difference(newCookies, oldCookies, boost::make_function_output_iterator(reportAppeared)); return oldCookies == newCookies; }

Page 45: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 45

bool doCompare(const Bakery& oldBakery, const Bakery& newBakery) { auto oldCookies = collectCookies(oldBakery); auto newCookies = collectCookies(newBakery); auto reportLost = [](const Cookie& cookie) { std::cout << "We've lost a friend: " << cookie << "." << std::endl; }; auto reportAppeared = [](const Cookie& cookie) { std::cout << "We got a new friend: " << cookie << "." << std::endl; }; boost::range::set_difference(oldCookies, newCookies, boost::make_function_output_iterator(reportLost)); boost::range::set_difference(newCookies, oldCookies, boost::make_function_output_iterator(reportAppeared)); return oldCookies == newCookies; }

Page 46: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 46

bool doCompare(const Bakery* oldBakery, const Bakery* newBakery) { if (!oldBakery || !newBakery) { return false; } std::vector<Cookie> oldCookies; std::vector<Cookie> newCookies; std::vector<std::pair<Cookie, int>> diff; collectCookies(*oldBakery, oldCookies); collectCookies(*newBakery, newCookies); std::sort(oldCookies.begin(), oldCookies.end(), compareCookies); std::sort(newCookies.begin(), newCookies.end(), compareCookies); auto oldIt = oldCookies.begin(); auto newIt = newCookies.begin(); while ((oldIt != oldCookies.end()) || (newIt != newCookies.end())) { if (compareCookies(*oldIt, *newIt)) { diff.push_back(std::pair<Cookie, int>(*oldIt, 1)); ++oldIt; } else if (compareCookies(*newIt, *oldIt)) { diff.push_back(std::pair<Cookie, int>(*newIt, 2)); ++newIt; } else { ++oldIt; ++newIt; } } if (oldIt != oldCookies.end()) { for (; oldIt < oldCookies.end(); oldIt++) { diff.push_back(std::pair<Cookie, int>(*oldIt, 1)); } } if (newIt != newCookies.end()) { for (; newIt < newCookies.end(); newIt++) { diff.push_back(std::pair<Cookie, int>(*newIt, 2)); } } for (const auto& item : diff) { std::cout << "Bakery #" << item.second << " has a different cookie \"" << item.first.name << "\" (weight=" << item.first.weight << ", volume=" << item.first.volume << ", tastiness=" << item.first.tastiness << ")." << std::endl; } if (diff.size() > 0) return false; return true; }

bool doCompare(const Bakery& oldBakery, const Bakery& newBakery) { auto oldCookies = collectCookies(oldBakery); auto newCookies = collectCookies(newBakery); auto reportLost = [](const Cookie& cookie) { std::cout << "We've lost a friend: " << cookie << "." << std::endl; }; auto reportAppeared = [](const Cookie& cookie) { std::cout << "We got a new friend: " << cookie << "." << std::endl; }; boost::range::set_difference(oldCookies, newCookies, boost::make_function_output_iterator(reportLost)); boost::range::set_difference(newCookies, oldCookies, boost::make_function_output_iterator(reportAppeared)); return oldCookies == newCookies; }

Page 47: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

Код, использующий стандартные алгоритмы и контейнеры: Короче Проще Надёжнее Обычно эффективнее Проще переиспользовать Не привязан к конкретной платформе

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 47

Page 48: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

Советы: Мыслите на высоком уровне Код должен ясно выражать намерение Знайте свои инструменты и используйте их к месту

"Повседневный С++", Михаил Матросов, CEE-SECR 2015 48

// references // auto variables // auto function return type // move semantics // lambda functions operator<(); std::make_tuple(); std::tie();

std::make_pair(); std::vector<T>::emplace_back(); std::vector<T>::empty(); operator<<(); std::back_inserter(); std::set_difference(); boost::range::set_difference(); boost::make_function_output_iterator();

Page 49: Разработка ПО 20112015.secrus.org/2015/files/004_matrosov.pdf · 2015-10-23 · Парадигма RAII и исключения (exceptions) Алгоритмы и контейнеры

Мыслите на высоком уровне Код должен ясно выражать намерение Знайте свои инструменты и используйте их к месту

"Повседневный С++", Михаил Матросов, CEE-SECR 2015

// references // auto variables // auto function return type // move semantics // lambda functions operator<(); std::make_tuple(); std::tie();

std::make_pair(); std::vector<T>::emplace_back(); std::vector<T>::empty(); operator<<(); std::back_inserter(); std::set_difference(); boost::range::set_difference(); boost::make_function_output_iterator();

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