matrosov daily c++

57
Повседневный С++: boost и STL Михаил Матросов [email protected] [email protected] 1

Upload: corehardby

Post on 16-Apr-2017

375 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: Matrosov daily c++

Повседневный С++: boost и STL

Михаил Матросов[email protected]

[email protected]

1

Page 2: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

2

Page 3: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

3

С++17С++11/14

С++98

С

High level

Expert level

Modern C++

Page 4: Matrosov daily c++

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

Bjarne Stroustrup

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

4

Page 5: Matrosov daily c++

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

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

5

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

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

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

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

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

Page 6: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

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()))  {    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;}

Page 7: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

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 = collectSortedCookies(oldBakery);  auto newCookies = collectSortedCookies(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: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

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: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

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: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

10

Page 11: Matrosov daily c++

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

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

11

Page 12: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

12

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 13: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

13

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 14: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

14

λλ=:

Page 15: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

15

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 16: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

16

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 17: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

17

std::vector<Cookie> collectSortedCookies(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 = collectSortedCookies(oldBakery);  std::vector<Cookie> newCookies = collectSortedCookies(newBakery);

// ...

Page 18: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

18

Page 19: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

19

// ... 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 20: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

20

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 21: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

21

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 22: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

22

// ... 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 23: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

23

// ... 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 24: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

24

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 25: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

25

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 26: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

26

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 27: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

27

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 28: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

28

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(); } };

См. http://stackoverflow.com/q/6218812/261217

Page 29: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

29

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

Page 30: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

30

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

Page 31: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

31

Page 32: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

32

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 33: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

33

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 34: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

34

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 35: Matrosov daily c++

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;}

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

35

Page 36: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

36

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 37: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

37

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

Page 38: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

38

return diff.empty();

Page 39: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

39

Page 40: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

40

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 83 6

oldCookies

newCookies

diff

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

Page 41: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

41

Page 42: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

42

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 43: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

43

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 44: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

44

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 45: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

45

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 46: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

46

bool doCompare(const Bakery& oldBakery, const Bakery& newBakery){  std::vector<Cookie> oldCookies = collectSortedCookies(oldBakery);  std::vector<Cookie> newCookies = collectSortedCookies(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: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

47

bool doCompare(const Bakery& oldBakery, const Bakery& newBakery){  auto oldCookies = collectSortedCookies(oldBakery);  auto newCookies = collectSortedCookies(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 48: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

48

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 = collectSortedCookies(oldBakery);  auto newCookies = collectSortedCookies(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 49: Matrosov daily c++

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

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

49

Page 50: Matrosov daily c++

И ещё немного по

теме…"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf

201650

Page 51: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

51

struct Cookie{  double weight;  double volume;  std::string name;  int tastiness;  auto rank() const {   return std::tie(tastiness, weight, volume, name); } };

Page 52: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

52

struct Cookie{  double weight;  double volume;  std::string name;  int tastiness; double density() const {   return weight / volume; } auto rank() const {   return std::tie(tastiness, density(), name); // Any problems here?.. }};

Page 53: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

53

struct Cookie{  double weight;  double volume;  std::string name;  int tastiness; double density() const {   return weight / volume; } auto rank() const { return std::make_tuple(tastiness, density(), std::ref(name)); }};

Page 54: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

54

struct Cookie{  double weight;  double volume;  std::string name;  int tastiness; double density() const {   return weight / volume; } auto rank() const // -> std::tuple<int, double, const std::string&> { return std::make_tuple(tastiness, density(), std::ref(name)); }};

Page 55: Matrosov daily c++

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

55

auto f = [](/* ... */) { /* ... */ };

boost::make_function_output_iterator(f) -> boost::iterators::function_output_iterator<LambdaAnonymousType>

template <class UnaryFunction>class function_output_iterator { // ...  UnaryFunction m_f;};

auto it1 = boost::make_function_output_iterator(f); // Not assignableauto it2 = boost::make_function_output_iterator(std::ref(f)); // Assignable

Page 56: Matrosov daily c++

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

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

56

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

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 57: Matrosov daily c++

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

"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016

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();

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

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

57