SlideShare a Scribd company logo
Повседневный С++: boost и STL
Михаил Матросов
mikhail.matrosov@gmail.com
mmatrosov@aligntech.com
1
2
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 3
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 4
С++17
С++11/14
С++98
С
High level
Expert level
Modern C++
“Within C++ is a smaller, simpler, safer
language struggling to get out”
Bjarne Stroustrup
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 5
High level:
 Парадигма RAII и исключения (exceptions)
 Алгоритмы и контейнеры STL и boost
 Семантика перемещения
 λ-функции
 Классы и конструкторы
 Простые шаблоны
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 6
Expert level:
 Операторы new/delete, владеющие
указатели
 Пользовательские операции копирования
и перемещения
 Пользовательские деструкторы
 Закрытое, защищённое, ромбовидное,
виртуальное наследование
 Шаблонная магия, SFINAE
 Все функции языка Си, препроцессор
 «Голые» циклы
Классический слайд с телом и заголовком
7
Which boost
features overlap
with C++11?
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 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);
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()))
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 9
bool doCompare(const Bakery* oldBakery, const Bakery* newBakery)
{
if (!oldBakery || !newBakery)
{
return false;
}
std::vector<Cookie> oldCookies;
std::vector<Cookie> newCookies;
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();
std::vector<std::pair<Cookie, int>> diff;
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)
{
std::vector<Cookie> oldCookies = collectSortedCookies(oldBakery);
std::vector<Cookie> newCookies = collectSortedCookies(newBakery);
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;
}
return lostCookies.empty() && appearedCookies.empty();
}
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 10
bool doCompare(const Bakery* oldBakery, const Bakery* newBakery)
{
if (!oldBakery || !newBakery)
{
return false;
}
std::vector<Cookie> oldCookies;
std::vector<Cookie> newCookies;
collectCookies(*oldBakery, oldCookies);
collectCookies(*newBakery, newCookies);
// ...
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 11
bool doCompare(const Bakery& oldBakery, const Bakery& newBakery)
{
std::vector<Cookie> oldCookies;
std::vector<Cookie> newCookies;
collectCookies(oldBakery, oldCookies);
collectCookies(newBakery, newCookies);
// ...
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 12
bool doCompare(const Bakery& oldBakery, const Bakery& newBakery)
{
std::vector<Cookie> oldCookies;
std::vector<Cookie> newCookies;
collectCookies(oldBakery, oldCookies);
collectCookies(newBakery, newCookies);
// ...
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 13
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 14
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);
// ...
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 15
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);
// ...
In-depth: Functional programming in C++
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 16
λλ
=:
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 17
// ...
std::sort(oldCookies.begin(), oldCookies.end(), compareCookies);
std::sort(newCookies.begin(), newCookies.end(), compareCookies);
auto oldIt = oldCookies.begin();
auto newIt = newCookies.begin();
std::vector<std::pair<Cookie, int>> diff;
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))
{
// ...
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 18
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;
}
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 19
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;
}
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 20
// ...
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))
{
// ...
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 21
// ...
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)
{
// ...
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 22
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;
}
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 23
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);
}
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 24
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);
}
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 25
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);
}
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 26
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& a, const Cookie& b)
{
return a.rank() < b.rank();
}
Implementing comparison operators via 'tuple' and 'tie', a good idea?
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 27
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& a, const Cookie& b)
{
return a.rank() < b.rank();
}
Implementing comparison operators via 'tuple' and 'tie', a good idea?
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 28
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& a, const Cookie& b)
{
return a.rank() < b.rank();
}
bool operator==(const Cookie& a, const Cookie& b)
{
return a.rank() == b.rank();
}
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 29
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 30
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());
// ...
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 31
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());
// ...
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 32
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);
// ...
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 33
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 34
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;
}
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 35
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;
}
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 36
std::vector<std::pair<Cookie, int>> diff;
// ...
if (*oldIt < *newIt)
{
diff.push_back({ *oldIt, 1 });
++oldIt;
}
else if (*newIt < *oldIt)
{
diff.push_back({ *newIt, 2 });
++newIt;
}
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 37
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;
}
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", Михаил Матросов, C++ Russia 2016 38
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 39
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 << ")";
}
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 40
if (diff.size() > 0)
return false;
return true;
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 41
return diff.empty();
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 42
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 43
auto oldIt = oldCookies.begin();
auto newIt = newCookies.begin();
std::vector<std::pair<Cookie, int>> diff;
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
Ошибка. Должно быть &&
Sean Parent: C++ Seasoning (no raw loops)
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 44
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 45
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));
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 46
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));
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 47
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;
}
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 48
bool doCompare(const Bakery& oldBakery, const Bakery& newBakery)
{
std::vector<Cookie> oldCookies = collectSortedCookies(oldBakery);
std::vector<Cookie> newCookies = collectSortedCookies(newBakery);
return lostCookies.empty() && appearedCookies.empty();
}
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;
}
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 49
bool doCompare(const Bakery* oldBakery, const Bakery* newBakery)
{
if (!oldBakery || !newBakery)
{
return false;
}
std::vector<Cookie> oldCookies;
std::vector<Cookie> newCookies;
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();
std::vector<std::pair<Cookie, int>> diff;
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)
{
std::vector<Cookie> oldCookies = collectSortedCookies(oldBakery);
std::vector<Cookie> newCookies = collectSortedCookies(newBakery);
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;
}
return lostCookies.empty() && appearedCookies.empty();
}
Код, использующий стандартные алгоритмы и контейнеры:
 Короче
 Проще
 Надёжнее
 Обычно эффективнее
 Проще переиспользовать
 Не привязан к конкретной платформе
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 50
И ещё немного
по теме…
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 51
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 52
struct Cookie
{
double weight;
double volume;
std::string name;
int tastiness;
auto rank() const
{
return std::tie(tastiness, weight, volume, name);
}
};
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 53
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);
}
};
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 54
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));
}
};
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 55
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));
}
};
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 56
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;
}
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 57
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));
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 58
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; // was "lostCookies.empty() && appearedCookies.empty()"
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 59
auto f = [](int x) { std::cout << x; };
auto it = boost::make_function_output_iterator(f);
decltype(it) it2 = it; // Ok, copied
it2 = it; // Does not compile, cannot assign!
std::function<void(int)> f = [](int x) { std::cout << x; };
auto it = boost::make_function_output_iterator(f);
decltype(it) it2 = it; // Ok, copied
it2 = it; // Ok, iterator holds an std::function instance
auto f = [](int x) { std::cout << x; };
auto it = boost::make_function_output_iterator(std::ref(f));
decltype(it) it2 = it; // Ok, copied
it2 = it; // Ok, iterator holds a reference
auto f = +[](int x) { std::cout << x; };
auto it = boost::make_function_output_iterator(f);
decltype(it) it2 = it; // Ok, copied
it2 = it; // Ok, note the plus before [], it triggers special C++ magic
Resolving ambiguous overload
on function pointer and
std::function for a lambda using +
boost::function_output_iterator
constructed from lambda
function is not assignable
Советы:
 Мыслите на высоком уровне
 Код должен ясно выражать намерение
 Знайте свои инструменты и используйте их к месту
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 60
// references
// auto variables
// auto function return type
// move semantics
// lambda functions
operator<();
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();
std::function<>
 Мыслите на высоком уровне
 Код должен ясно выражать намерение
 Знайте свои инструменты и используйте их к месту
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 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();
std::function<>
Спасибо за внимание!
// references
// auto variables
// auto function return type
// move semantics
// lambda functions
operator<();
std::make_tuple();
std::tie();
std::ref();
61
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 62
compareRanked(Cookie const&, Cookie const&):
movl 16(%rsi), %edx
cmpl %edx, 16(%rdi)
movl $1, %eax
jl .L2
movl $0, %eax
jg .L2
movsd (%rdi), %xmm1
movl $1, %eax
movsd (%rsi), %xmm0
ucomisd %xmm1, %xmm0
ja .L2
xorl %eax, %eax
ucomisd %xmm0, %xmm1
ja .L2
movsd 8(%rsi), %xmm0
ucomisd 8(%rdi), %xmm0
seta %al
.L2:
rep ret
compareDirect(Cookie const&, Cookie const&):
movl 16(%rsi), %eax
cmpl %eax, 16(%rdi)
je .L9
setl %al
ret
.L9:
movsd (%rdi), %xmm0
movsd (%rsi), %xmm1
ucomisd %xmm1, %xmm0
jp .L13
jne .L13
movsd 8(%rsi), %xmm0
ucomisd 8(%rdi), %xmm0
seta %al
ret
.L13:
ucomisd %xmm0, %xmm1
seta %al
ret
Ссылки
 Which boost features overlap with C++11?
 In-depth: Functional programming in C++
 Implementing comparison operators via 'tuple' and 'tie', a good idea?
 Sean Parent: C++ Seasoning (no raw loops)
 boost::function_output_iterator constructed from lambda function is not assignable
 Resolving ambiguous overload on function pointer and std::function for a lambda using +
"Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 63

More Related Content

What's hot

Sokoban Game Development Using Java ( Updated using Screenshots & Class Diagr...
Sokoban Game Development Using Java ( Updated using Screenshots & Class Diagr...Sokoban Game Development Using Java ( Updated using Screenshots & Class Diagr...
Sokoban Game Development Using Java ( Updated using Screenshots & Class Diagr...
British Council
 
The Ring programming language version 1.6 book - Part 71 of 189
The Ring programming language version 1.6 book - Part 71 of 189The Ring programming language version 1.6 book - Part 71 of 189
The Ring programming language version 1.6 book - Part 71 of 189
Mahmoud Samir Fayed
 
The Ring programming language version 1.10 book - Part 64 of 212
The Ring programming language version 1.10 book - Part 64 of 212The Ring programming language version 1.10 book - Part 64 of 212
The Ring programming language version 1.10 book - Part 64 of 212
Mahmoud Samir Fayed
 
The Ring programming language version 1.6 book - Part 62 of 189
The Ring programming language version 1.6 book - Part 62 of 189The Ring programming language version 1.6 book - Part 62 of 189
The Ring programming language version 1.6 book - Part 62 of 189
Mahmoud Samir Fayed
 
Node.js and angular js
Node.js and angular jsNode.js and angular js
Node.js and angular js
HyungKuIm
 
Ocr code
Ocr codeOcr code
Ocr code
wi7sonjoseph
 
The Ring programming language version 1.5.4 book - Part 59 of 185
The Ring programming language version 1.5.4 book - Part 59 of 185The Ring programming language version 1.5.4 book - Part 59 of 185
The Ring programming language version 1.5.4 book - Part 59 of 185
Mahmoud Samir Fayed
 
The Ring programming language version 1.7 book - Part 63 of 196
The Ring programming language version 1.7 book - Part 63 of 196The Ring programming language version 1.7 book - Part 63 of 196
The Ring programming language version 1.7 book - Part 63 of 196
Mahmoud Samir Fayed
 
The Ring programming language version 1.5.2 book - Part 63 of 181
The Ring programming language version 1.5.2 book - Part 63 of 181The Ring programming language version 1.5.2 book - Part 63 of 181
The Ring programming language version 1.5.2 book - Part 63 of 181
Mahmoud Samir Fayed
 
Lambda expressions in C++
Lambda expressions in C++Lambda expressions in C++
Lambda expressions in C++
Dimitrios Platis
 
The Ring programming language version 1.2 book - Part 44 of 84
The Ring programming language version 1.2 book - Part 44 of 84The Ring programming language version 1.2 book - Part 44 of 84
The Ring programming language version 1.2 book - Part 44 of 84
Mahmoud Samir Fayed
 
Writing SOLID C++ [gbgcpp meetup @ Zenseact]
Writing SOLID C++ [gbgcpp meetup @ Zenseact]Writing SOLID C++ [gbgcpp meetup @ Zenseact]
Writing SOLID C++ [gbgcpp meetup @ Zenseact]
Dimitrios Platis
 
Shift Remote FRONTEND: Reactivity in Vue.JS 3 - Marko Boskovic (Barrage)
Shift Remote FRONTEND: Reactivity in Vue.JS 3 - Marko Boskovic (Barrage)Shift Remote FRONTEND: Reactivity in Vue.JS 3 - Marko Boskovic (Barrage)
Shift Remote FRONTEND: Reactivity in Vue.JS 3 - Marko Boskovic (Barrage)
Shift Conference
 
The Ring programming language version 1.5.1 book - Part 51 of 180
The Ring programming language version 1.5.1 book - Part 51 of 180The Ring programming language version 1.5.1 book - Part 51 of 180
The Ring programming language version 1.5.1 book - Part 51 of 180
Mahmoud Samir Fayed
 
The State of JavaScript
The State of JavaScriptThe State of JavaScript
The State of JavaScript
Domenic Denicola
 
Varnish kann alles
Varnish kann allesVarnish kann alles
Varnish kann alles
Bild GmbH & Co. KG
 

What's hot (20)

Sokoban Game Development Using Java ( Updated using Screenshots & Class Diagr...
Sokoban Game Development Using Java ( Updated using Screenshots & Class Diagr...Sokoban Game Development Using Java ( Updated using Screenshots & Class Diagr...
Sokoban Game Development Using Java ( Updated using Screenshots & Class Diagr...
 
Ac2
Ac2Ac2
Ac2
 
The Ring programming language version 1.6 book - Part 71 of 189
The Ring programming language version 1.6 book - Part 71 of 189The Ring programming language version 1.6 book - Part 71 of 189
The Ring programming language version 1.6 book - Part 71 of 189
 
Pemrograman visual
Pemrograman visualPemrograman visual
Pemrograman visual
 
The Ring programming language version 1.10 book - Part 64 of 212
The Ring programming language version 1.10 book - Part 64 of 212The Ring programming language version 1.10 book - Part 64 of 212
The Ring programming language version 1.10 book - Part 64 of 212
 
D3.js workshop
D3.js workshopD3.js workshop
D3.js workshop
 
The Ring programming language version 1.6 book - Part 62 of 189
The Ring programming language version 1.6 book - Part 62 of 189The Ring programming language version 1.6 book - Part 62 of 189
The Ring programming language version 1.6 book - Part 62 of 189
 
Node.js and angular js
Node.js and angular jsNode.js and angular js
Node.js and angular js
 
Ocr code
Ocr codeOcr code
Ocr code
 
The Ring programming language version 1.5.4 book - Part 59 of 185
The Ring programming language version 1.5.4 book - Part 59 of 185The Ring programming language version 1.5.4 book - Part 59 of 185
The Ring programming language version 1.5.4 book - Part 59 of 185
 
The Ring programming language version 1.7 book - Part 63 of 196
The Ring programming language version 1.7 book - Part 63 of 196The Ring programming language version 1.7 book - Part 63 of 196
The Ring programming language version 1.7 book - Part 63 of 196
 
The Ring programming language version 1.5.2 book - Part 63 of 181
The Ring programming language version 1.5.2 book - Part 63 of 181The Ring programming language version 1.5.2 book - Part 63 of 181
The Ring programming language version 1.5.2 book - Part 63 of 181
 
openGl example
openGl exampleopenGl example
openGl example
 
Lambda expressions in C++
Lambda expressions in C++Lambda expressions in C++
Lambda expressions in C++
 
The Ring programming language version 1.2 book - Part 44 of 84
The Ring programming language version 1.2 book - Part 44 of 84The Ring programming language version 1.2 book - Part 44 of 84
The Ring programming language version 1.2 book - Part 44 of 84
 
Writing SOLID C++ [gbgcpp meetup @ Zenseact]
Writing SOLID C++ [gbgcpp meetup @ Zenseact]Writing SOLID C++ [gbgcpp meetup @ Zenseact]
Writing SOLID C++ [gbgcpp meetup @ Zenseact]
 
Shift Remote FRONTEND: Reactivity in Vue.JS 3 - Marko Boskovic (Barrage)
Shift Remote FRONTEND: Reactivity in Vue.JS 3 - Marko Boskovic (Barrage)Shift Remote FRONTEND: Reactivity in Vue.JS 3 - Marko Boskovic (Barrage)
Shift Remote FRONTEND: Reactivity in Vue.JS 3 - Marko Boskovic (Barrage)
 
The Ring programming language version 1.5.1 book - Part 51 of 180
The Ring programming language version 1.5.1 book - Part 51 of 180The Ring programming language version 1.5.1 book - Part 51 of 180
The Ring programming language version 1.5.1 book - Part 51 of 180
 
The State of JavaScript
The State of JavaScriptThe State of JavaScript
The State of JavaScript
 
Varnish kann alles
Varnish kann allesVarnish kann alles
Varnish kann alles
 

Viewers also liked

Повседневный С++: алгоритмы и итераторы
Повседневный С++: алгоритмы и итераторы Повседневный С++: алгоритмы и итераторы
Повседневный С++: алгоритмы и итераторы
corehard_by
 
Антон Бикинеев, Reflection in C++Next
Антон Бикинеев,  Reflection in C++NextАнтон Бикинеев,  Reflection in C++Next
Антон Бикинеев, Reflection in C++Next
Sergey Platonov
 
Clang tidy
Clang tidyClang tidy
Clang tidy
Yury Yafimachau
 
Parallel STL
Parallel STLParallel STL
Parallel STL
Evgeny Krutko
 
Догнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_castДогнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_cast
Roman Orlov
 
Фитнес для вашего кода: как держать его в форме
Фитнес для вашего кода: как держать его в формеФитнес для вашего кода: как держать его в форме
Фитнес для вашего кода: как держать его в форме
Ilia Shishkov
 
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against itEvgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
Sergey Platonov
 
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
Mikhail Matrosov
 
Василий Сорокин, Простой REST сервер на Qt с рефлексией
Василий Сорокин, Простой REST сервер на Qt с рефлексиейВасилий Сорокин, Простой REST сервер на Qt с рефлексией
Василий Сорокин, Простой REST сервер на Qt с рефлексией
Sergey Platonov
 
Антон Нонко, Классические строки в C++
Антон Нонко, Классические строки в C++Антон Нонко, Классические строки в C++
Антон Нонко, Классические строки в C++
Sergey Platonov
 
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворковНикита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Sergey Platonov
 
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
Sergey Platonov
 
Павел Довгалюк, Обратная отладка
Павел Довгалюк, Обратная отладкаПавел Довгалюк, Обратная отладка
Павел Довгалюк, Обратная отладка
Sergey Platonov
 
Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...
Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...
Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...
Sergey Platonov
 
Concepts lite
Concepts liteConcepts lite
Concepts lite
Platonov Sergey
 
Григорий Демченко, Универсальный адаптер
Григорий Демченко, Универсальный адаптерГригорий Демченко, Универсальный адаптер
Григорий Демченко, Универсальный адаптер
Sergey Platonov
 
Использование юнит-тестов для повышения качества разработки
Использование юнит-тестов для повышения качества разработкиИспользование юнит-тестов для повышения качества разработки
Использование юнит-тестов для повышения качества разработки
victor-yastrebov
 
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Platonov Sergey
 
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и JavascriptСергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Sergey Platonov
 
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловПолухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Sergey Platonov
 

Viewers also liked (20)

Повседневный С++: алгоритмы и итераторы
Повседневный С++: алгоритмы и итераторы Повседневный С++: алгоритмы и итераторы
Повседневный С++: алгоритмы и итераторы
 
Антон Бикинеев, Reflection in C++Next
Антон Бикинеев,  Reflection in C++NextАнтон Бикинеев,  Reflection in C++Next
Антон Бикинеев, Reflection in C++Next
 
Clang tidy
Clang tidyClang tidy
Clang tidy
 
Parallel STL
Parallel STLParallel STL
Parallel STL
 
Догнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_castДогнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_cast
 
Фитнес для вашего кода: как держать его в форме
Фитнес для вашего кода: как держать его в формеФитнес для вашего кода: как держать его в форме
Фитнес для вашего кода: как держать его в форме
 
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against itEvgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
 
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
 
Василий Сорокин, Простой REST сервер на Qt с рефлексией
Василий Сорокин, Простой REST сервер на Qt с рефлексиейВасилий Сорокин, Простой REST сервер на Qt с рефлексией
Василий Сорокин, Простой REST сервер на Qt с рефлексией
 
Антон Нонко, Классические строки в C++
Антон Нонко, Классические строки в C++Антон Нонко, Классические строки в C++
Антон Нонко, Классические строки в C++
 
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворковНикита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
 
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
 
Павел Довгалюк, Обратная отладка
Павел Довгалюк, Обратная отладкаПавел Довгалюк, Обратная отладка
Павел Довгалюк, Обратная отладка
 
Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...
Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...
Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...
 
Concepts lite
Concepts liteConcepts lite
Concepts lite
 
Григорий Демченко, Универсальный адаптер
Григорий Демченко, Универсальный адаптерГригорий Демченко, Универсальный адаптер
Григорий Демченко, Универсальный адаптер
 
Использование юнит-тестов для повышения качества разработки
Использование юнит-тестов для повышения качества разработкиИспользование юнит-тестов для повышения качества разработки
Использование юнит-тестов для повышения качества разработки
 
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
 
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и JavascriptСергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
 
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловПолухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
 

Similar to Михаил Матросов, Повседневный С++: boost и STL

Matrosov daily c++
Matrosov daily c++Matrosov daily c++
Matrosov daily c++
corehard_by
 
Back to Basics, webinar 2: La tua prima applicazione MongoDB
Back to Basics, webinar 2: La tua prima applicazione MongoDBBack to Basics, webinar 2: La tua prima applicazione MongoDB
Back to Basics, webinar 2: La tua prima applicazione MongoDB
MongoDB
 
The Ring programming language version 1.8 book - Part 74 of 202
The Ring programming language version 1.8 book - Part 74 of 202The Ring programming language version 1.8 book - Part 74 of 202
The Ring programming language version 1.8 book - Part 74 of 202
Mahmoud Samir Fayed
 
The Ring programming language version 1.6 book - Part 70 of 189
The Ring programming language version 1.6 book - Part 70 of 189The Ring programming language version 1.6 book - Part 70 of 189
The Ring programming language version 1.6 book - Part 70 of 189
Mahmoud Samir Fayed
 
2011 nri-pratiques tests-avancees
2011 nri-pratiques tests-avancees2011 nri-pratiques tests-avancees
2011 nri-pratiques tests-avancees
Nathaniel Richand
 
The Ring programming language version 1.7 book - Part 48 of 196
The Ring programming language version 1.7 book - Part 48 of 196The Ring programming language version 1.7 book - Part 48 of 196
The Ring programming language version 1.7 book - Part 48 of 196
Mahmoud Samir Fayed
 
Conceptos básicos. Seminario web 2: Su primera aplicación MongoDB
 Conceptos básicos. Seminario web 2: Su primera aplicación MongoDB Conceptos básicos. Seminario web 2: Su primera aplicación MongoDB
Conceptos básicos. Seminario web 2: Su primera aplicación MongoDB
MongoDB
 
OGDC2013_Lets remake the wheel_ Mr Nguyen Trung Hung
OGDC2013_Lets remake the wheel_ Mr Nguyen Trung HungOGDC2013_Lets remake the wheel_ Mr Nguyen Trung Hung
OGDC2013_Lets remake the wheel_ Mr Nguyen Trung Hung
ogdc
 
Ogdc 2013 lets remake the wheel
Ogdc 2013 lets remake the wheelOgdc 2013 lets remake the wheel
Ogdc 2013 lets remake the wheelSon Aris
 
The Ring programming language version 1.7 book - Part 72 of 196
The Ring programming language version 1.7 book - Part 72 of 196The Ring programming language version 1.7 book - Part 72 of 196
The Ring programming language version 1.7 book - Part 72 of 196
Mahmoud Samir Fayed
 
Drools 6.0 (CamelOne 2013)
Drools 6.0 (CamelOne 2013)Drools 6.0 (CamelOne 2013)
Drools 6.0 (CamelOne 2013)
Mark Proctor
 
Будь первым
Будь первымБудь первым
Будь первым
FDConf
 
The Ring programming language version 1.5 book - Part 8 of 31
The Ring programming language version 1.5 book - Part 8 of 31The Ring programming language version 1.5 book - Part 8 of 31
The Ring programming language version 1.5 book - Part 8 of 31
Mahmoud Samir Fayed
 
Blockchain com JavaScript
Blockchain com JavaScriptBlockchain com JavaScript
Blockchain com JavaScript
Beto Muniz
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVC
pootsbook
 
The Ring programming language version 1.8 book - Part 49 of 202
The Ring programming language version 1.8 book - Part 49 of 202The Ring programming language version 1.8 book - Part 49 of 202
The Ring programming language version 1.8 book - Part 49 of 202
Mahmoud Samir Fayed
 
The Ring programming language version 1.5.1 book - Part 64 of 180
The Ring programming language version 1.5.1 book - Part 64 of 180The Ring programming language version 1.5.1 book - Part 64 of 180
The Ring programming language version 1.5.1 book - Part 64 of 180
Mahmoud Samir Fayed
 
The Ring programming language version 1.4.1 book - Part 8 of 31
The Ring programming language version 1.4.1 book - Part 8 of 31The Ring programming language version 1.4.1 book - Part 8 of 31
The Ring programming language version 1.4.1 book - Part 8 of 31
Mahmoud Samir Fayed
 
NoSQL meets Microservices - Michael Hackstein
NoSQL meets Microservices - Michael HacksteinNoSQL meets Microservices - Michael Hackstein
NoSQL meets Microservices - Michael Hackstein
distributed matters
 

Similar to Михаил Матросов, Повседневный С++: boost и STL (20)

Matrosov daily c++
Matrosov daily c++Matrosov daily c++
Matrosov daily c++
 
Intro
IntroIntro
Intro
 
Back to Basics, webinar 2: La tua prima applicazione MongoDB
Back to Basics, webinar 2: La tua prima applicazione MongoDBBack to Basics, webinar 2: La tua prima applicazione MongoDB
Back to Basics, webinar 2: La tua prima applicazione MongoDB
 
The Ring programming language version 1.8 book - Part 74 of 202
The Ring programming language version 1.8 book - Part 74 of 202The Ring programming language version 1.8 book - Part 74 of 202
The Ring programming language version 1.8 book - Part 74 of 202
 
The Ring programming language version 1.6 book - Part 70 of 189
The Ring programming language version 1.6 book - Part 70 of 189The Ring programming language version 1.6 book - Part 70 of 189
The Ring programming language version 1.6 book - Part 70 of 189
 
2011 nri-pratiques tests-avancees
2011 nri-pratiques tests-avancees2011 nri-pratiques tests-avancees
2011 nri-pratiques tests-avancees
 
The Ring programming language version 1.7 book - Part 48 of 196
The Ring programming language version 1.7 book - Part 48 of 196The Ring programming language version 1.7 book - Part 48 of 196
The Ring programming language version 1.7 book - Part 48 of 196
 
Conceptos básicos. Seminario web 2: Su primera aplicación MongoDB
 Conceptos básicos. Seminario web 2: Su primera aplicación MongoDB Conceptos básicos. Seminario web 2: Su primera aplicación MongoDB
Conceptos básicos. Seminario web 2: Su primera aplicación MongoDB
 
OGDC2013_Lets remake the wheel_ Mr Nguyen Trung Hung
OGDC2013_Lets remake the wheel_ Mr Nguyen Trung HungOGDC2013_Lets remake the wheel_ Mr Nguyen Trung Hung
OGDC2013_Lets remake the wheel_ Mr Nguyen Trung Hung
 
Ogdc 2013 lets remake the wheel
Ogdc 2013 lets remake the wheelOgdc 2013 lets remake the wheel
Ogdc 2013 lets remake the wheel
 
The Ring programming language version 1.7 book - Part 72 of 196
The Ring programming language version 1.7 book - Part 72 of 196The Ring programming language version 1.7 book - Part 72 of 196
The Ring programming language version 1.7 book - Part 72 of 196
 
Drools 6.0 (CamelOne 2013)
Drools 6.0 (CamelOne 2013)Drools 6.0 (CamelOne 2013)
Drools 6.0 (CamelOne 2013)
 
Будь первым
Будь первымБудь первым
Будь первым
 
The Ring programming language version 1.5 book - Part 8 of 31
The Ring programming language version 1.5 book - Part 8 of 31The Ring programming language version 1.5 book - Part 8 of 31
The Ring programming language version 1.5 book - Part 8 of 31
 
Blockchain com JavaScript
Blockchain com JavaScriptBlockchain com JavaScript
Blockchain com JavaScript
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVC
 
The Ring programming language version 1.8 book - Part 49 of 202
The Ring programming language version 1.8 book - Part 49 of 202The Ring programming language version 1.8 book - Part 49 of 202
The Ring programming language version 1.8 book - Part 49 of 202
 
The Ring programming language version 1.5.1 book - Part 64 of 180
The Ring programming language version 1.5.1 book - Part 64 of 180The Ring programming language version 1.5.1 book - Part 64 of 180
The Ring programming language version 1.5.1 book - Part 64 of 180
 
The Ring programming language version 1.4.1 book - Part 8 of 31
The Ring programming language version 1.4.1 book - Part 8 of 31The Ring programming language version 1.4.1 book - Part 8 of 31
The Ring programming language version 1.4.1 book - Part 8 of 31
 
NoSQL meets Microservices - Michael Hackstein
NoSQL meets Microservices - Michael HacksteinNoSQL meets Microservices - Michael Hackstein
NoSQL meets Microservices - Michael Hackstein
 

More from Sergey Platonov

Лев Казаркин, Удивительные приключения регистров SSE или в поисках одного бага
Лев Казаркин, Удивительные приключения регистров SSE или в поисках одного багаЛев Казаркин, Удивительные приключения регистров SSE или в поисках одного бага
Лев Казаркин, Удивительные приключения регистров SSE или в поисках одного бага
Sergey Platonov
 
Антон Бикинеев, Writing good std::future&lt; C++ >
Антон Бикинеев, Writing good std::future&lt; C++ >Антон Бикинеев, Writing good std::future&lt; C++ >
Антон Бикинеев, Writing good std::future&lt; C++ >
Sergey Platonov
 
Павел Филонов, Разделяй и управляй вместе с Conan.io
Павел Филонов, Разделяй и управляй вместе с Conan.ioПавел Филонов, Разделяй и управляй вместе с Conan.io
Павел Филонов, Разделяй и управляй вместе с Conan.io
Sergey Platonov
 
Григорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизацияГригорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизация
Sergey Platonov
 
Антон Полухин. C++17
Антон Полухин. C++17Антон Полухин. C++17
Антон Полухин. C++17
Sergey Platonov
 
Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++
Sergey Platonov
 
Денис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на Qt
Денис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на QtДенис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на Qt
Денис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на Qt
Sergey Platonov
 
Алексей Кутумов, Coroutines everywhere
Алексей Кутумов, Coroutines everywhereАлексей Кутумов, Coroutines everywhere
Алексей Кутумов, Coroutines everywhere
Sergey Platonov
 
Дмитрий Нестерук, Паттерны проектирования в XXI веке
Дмитрий Нестерук, Паттерны проектирования в XXI векеДмитрий Нестерук, Паттерны проектирования в XXI веке
Дмитрий Нестерук, Паттерны проектирования в XXI веке
Sergey Platonov
 
Dori Exterman, Considerations for choosing the parallel computing strategy th...
Dori Exterman, Considerations for choosing the parallel computing strategy th...Dori Exterman, Considerations for choosing the parallel computing strategy th...
Dori Exterman, Considerations for choosing the parallel computing strategy th...
Sergey Platonov
 
Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++
Sergey Platonov
 
Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++
Sergey Platonov
 
Алексей Кутумов, Вектор с нуля
Алексей Кутумов, Вектор с нуляАлексей Кутумов, Вектор с нуля
Алексей Кутумов, Вектор с нуля
Sergey Platonov
 
Kirk Shoop, Reactive programming in C++
Kirk Shoop, Reactive programming in C++Kirk Shoop, Reactive programming in C++
Kirk Shoop, Reactive programming in C++
Sergey Platonov
 
Дмитрий Демчук. Кроссплатформенный краш-репорт
Дмитрий Демчук. Кроссплатформенный краш-репортДмитрий Демчук. Кроссплатформенный краш-репорт
Дмитрий Демчук. Кроссплатформенный краш-репорт
Sergey Platonov
 
Илья Шишков, Принципы создания тестируемого кода
Илья Шишков, Принципы создания тестируемого кодаИлья Шишков, Принципы создания тестируемого кода
Илья Шишков, Принципы создания тестируемого кода
Sergey Platonov
 
Антон Наумович, Система автоматической крэш-аналитики своими средствами
Антон Наумович, Система автоматической крэш-аналитики своими средствамиАнтон Наумович, Система автоматической крэш-аналитики своими средствами
Антон Наумович, Система автоматической крэш-аналитики своими средствами
Sergey Platonov
 
Андрей Карпов, Приватные байки от разработчиков анализатора кода
Андрей Карпов, Приватные байки от разработчиков анализатора кодаАндрей Карпов, Приватные байки от разработчиков анализатора кода
Андрей Карпов, Приватные байки от разработчиков анализатора кода
Sergey Platonov
 
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Sergey Platonov
 

More from Sergey Platonov (19)

Лев Казаркин, Удивительные приключения регистров SSE или в поисках одного бага
Лев Казаркин, Удивительные приключения регистров SSE или в поисках одного багаЛев Казаркин, Удивительные приключения регистров SSE или в поисках одного бага
Лев Казаркин, Удивительные приключения регистров SSE или в поисках одного бага
 
Антон Бикинеев, Writing good std::future&lt; C++ >
Антон Бикинеев, Writing good std::future&lt; C++ >Антон Бикинеев, Writing good std::future&lt; C++ >
Антон Бикинеев, Writing good std::future&lt; C++ >
 
Павел Филонов, Разделяй и управляй вместе с Conan.io
Павел Филонов, Разделяй и управляй вместе с Conan.ioПавел Филонов, Разделяй и управляй вместе с Conan.io
Павел Филонов, Разделяй и управляй вместе с Conan.io
 
Григорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизацияГригорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизация
 
Антон Полухин. C++17
Антон Полухин. C++17Антон Полухин. C++17
Антон Полухин. C++17
 
Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++
 
Денис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на Qt
Денис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на QtДенис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на Qt
Денис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на Qt
 
Алексей Кутумов, Coroutines everywhere
Алексей Кутумов, Coroutines everywhereАлексей Кутумов, Coroutines everywhere
Алексей Кутумов, Coroutines everywhere
 
Дмитрий Нестерук, Паттерны проектирования в XXI веке
Дмитрий Нестерук, Паттерны проектирования в XXI векеДмитрий Нестерук, Паттерны проектирования в XXI веке
Дмитрий Нестерук, Паттерны проектирования в XXI веке
 
Dori Exterman, Considerations for choosing the parallel computing strategy th...
Dori Exterman, Considerations for choosing the parallel computing strategy th...Dori Exterman, Considerations for choosing the parallel computing strategy th...
Dori Exterman, Considerations for choosing the parallel computing strategy th...
 
Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++
 
Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++
 
Алексей Кутумов, Вектор с нуля
Алексей Кутумов, Вектор с нуляАлексей Кутумов, Вектор с нуля
Алексей Кутумов, Вектор с нуля
 
Kirk Shoop, Reactive programming in C++
Kirk Shoop, Reactive programming in C++Kirk Shoop, Reactive programming in C++
Kirk Shoop, Reactive programming in C++
 
Дмитрий Демчук. Кроссплатформенный краш-репорт
Дмитрий Демчук. Кроссплатформенный краш-репортДмитрий Демчук. Кроссплатформенный краш-репорт
Дмитрий Демчук. Кроссплатформенный краш-репорт
 
Илья Шишков, Принципы создания тестируемого кода
Илья Шишков, Принципы создания тестируемого кодаИлья Шишков, Принципы создания тестируемого кода
Илья Шишков, Принципы создания тестируемого кода
 
Антон Наумович, Система автоматической крэш-аналитики своими средствами
Антон Наумович, Система автоматической крэш-аналитики своими средствамиАнтон Наумович, Система автоматической крэш-аналитики своими средствами
Антон Наумович, Система автоматической крэш-аналитики своими средствами
 
Андрей Карпов, Приватные байки от разработчиков анализатора кода
Андрей Карпов, Приватные байки от разработчиков анализатора кодаАндрей Карпов, Приватные байки от разработчиков анализатора кода
Андрей Карпов, Приватные байки от разработчиков анализатора кода
 
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
 

Recently uploaded

A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
Philip Schwarz
 
May Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdfMay Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdf
Adele Miller
 
Enhancing Research Orchestration Capabilities at ORNL.pdf
Enhancing Research Orchestration Capabilities at ORNL.pdfEnhancing Research Orchestration Capabilities at ORNL.pdf
Enhancing Research Orchestration Capabilities at ORNL.pdf
Globus
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
Łukasz Chruściel
 
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOMLORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
lorraineandreiamcidl
 
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptxText-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
ShamsuddeenMuhammadA
 
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Globus
 
Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024
Globus
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
NYGGS Automation Suite
 
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
Juraj Vysvader
 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
rickgrimesss22
 
First Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User EndpointsFirst Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User Endpoints
Globus
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
Aftab Hussain
 
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdfAutomated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
timtebeek1
 
Empowering Growth with Best Software Development Company in Noida - Deuglo
Empowering Growth with Best Software  Development Company in Noida - DeugloEmpowering Growth with Best Software  Development Company in Noida - Deuglo
Empowering Growth with Best Software Development Company in Noida - Deuglo
Deuglo Infosystem Pvt Ltd
 
BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024
Ortus Solutions, Corp
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Neo4j
 
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata
 
Lecture 1 Introduction to games development
Lecture 1 Introduction to games developmentLecture 1 Introduction to games development
Lecture 1 Introduction to games development
abdulrafaychaudhry
 
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing SuiteAI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
Google
 

Recently uploaded (20)

A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
 
May Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdfMay Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdf
 
Enhancing Research Orchestration Capabilities at ORNL.pdf
Enhancing Research Orchestration Capabilities at ORNL.pdfEnhancing Research Orchestration Capabilities at ORNL.pdf
Enhancing Research Orchestration Capabilities at ORNL.pdf
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
 
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOMLORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
 
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptxText-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
 
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
 
Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
 
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
 
First Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User EndpointsFirst Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User Endpoints
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
 
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdfAutomated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
 
Empowering Growth with Best Software Development Company in Noida - Deuglo
Empowering Growth with Best Software  Development Company in Noida - DeugloEmpowering Growth with Best Software  Development Company in Noida - Deuglo
Empowering Growth with Best Software Development Company in Noida - Deuglo
 
BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
 
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024
 
Lecture 1 Introduction to games development
Lecture 1 Introduction to games developmentLecture 1 Introduction to games development
Lecture 1 Introduction to games development
 
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing SuiteAI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
 

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

  • 1. Повседневный С++: boost и STL Михаил Матросов mikhail.matrosov@gmail.com mmatrosov@aligntech.com 1
  • 2. 2
  • 3. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 3
  • 4. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 4 С++17 С++11/14 С++98 С High level Expert level Modern C++
  • 5. “Within C++ is a smaller, simpler, safer language struggling to get out” Bjarne Stroustrup "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 5
  • 6. High level:  Парадигма RAII и исключения (exceptions)  Алгоритмы и контейнеры STL и boost  Семантика перемещения  λ-функции  Классы и конструкторы  Простые шаблоны "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 6 Expert level:  Операторы new/delete, владеющие указатели  Пользовательские операции копирования и перемещения  Пользовательские деструкторы  Закрытое, защищённое, ромбовидное, виртуальное наследование  Шаблонная магия, SFINAE  Все функции языка Си, препроцессор  «Голые» циклы Классический слайд с телом и заголовком
  • 8. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 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); 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()))
  • 9. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 9 bool doCompare(const Bakery* oldBakery, const Bakery* newBakery) { if (!oldBakery || !newBakery) { return false; } std::vector<Cookie> oldCookies; std::vector<Cookie> newCookies; 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(); std::vector<std::pair<Cookie, int>> diff; 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) { std::vector<Cookie> oldCookies = collectSortedCookies(oldBakery); std::vector<Cookie> newCookies = collectSortedCookies(newBakery); 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; } return lostCookies.empty() && appearedCookies.empty(); }
  • 10. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 10 bool doCompare(const Bakery* oldBakery, const Bakery* newBakery) { if (!oldBakery || !newBakery) { return false; } std::vector<Cookie> oldCookies; std::vector<Cookie> newCookies; collectCookies(*oldBakery, oldCookies); collectCookies(*newBakery, newCookies); // ...
  • 11. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 11 bool doCompare(const Bakery& oldBakery, const Bakery& newBakery) { std::vector<Cookie> oldCookies; std::vector<Cookie> newCookies; collectCookies(oldBakery, oldCookies); collectCookies(newBakery, newCookies); // ...
  • 12. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 12
  • 13. bool doCompare(const Bakery& oldBakery, const Bakery& newBakery) { std::vector<Cookie> oldCookies; std::vector<Cookie> newCookies; collectCookies(oldBakery, oldCookies); collectCookies(newBakery, newCookies); // ... "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 13
  • 14. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 14 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); // ...
  • 15. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 15 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); // ... In-depth: Functional programming in C++
  • 16. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 16 λλ =:
  • 17. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 17 // ... std::sort(oldCookies.begin(), oldCookies.end(), compareCookies); std::sort(newCookies.begin(), newCookies.end(), compareCookies); auto oldIt = oldCookies.begin(); auto newIt = newCookies.begin(); std::vector<std::pair<Cookie, int>> diff; 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)) { // ...
  • 18. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 18 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; }
  • 19. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 19 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; }
  • 20. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 20 // ... 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)) { // ...
  • 21. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 21 // ... 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) { // ...
  • 22. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 22 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; }
  • 23. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 23 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); }
  • 24. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 24 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); }
  • 25. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 25 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); }
  • 26. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 26 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& a, const Cookie& b) { return a.rank() < b.rank(); } Implementing comparison operators via 'tuple' and 'tie', a good idea?
  • 27. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 27 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& a, const Cookie& b) { return a.rank() < b.rank(); } Implementing comparison operators via 'tuple' and 'tie', a good idea?
  • 28. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 28 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& a, const Cookie& b) { return a.rank() < b.rank(); } bool operator==(const Cookie& a, const Cookie& b) { return a.rank() == b.rank(); }
  • 29. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 29
  • 30. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 30 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()); // ...
  • 31. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 31 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()); // ...
  • 32. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 32 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); // ...
  • 33. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 33
  • 34. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 34 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; }
  • 35. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 35 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; }
  • 36. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 36 std::vector<std::pair<Cookie, int>> diff; // ... if (*oldIt < *newIt) { diff.push_back({ *oldIt, 1 }); ++oldIt; } else if (*newIt < *oldIt) { diff.push_back({ *newIt, 2 }); ++newIt; }
  • 37. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 37 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; }
  • 38. 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", Михаил Матросов, C++ Russia 2016 38
  • 39. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 39 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 << ")"; }
  • 40. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 40 if (diff.size() > 0) return false; return true;
  • 41. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 41 return diff.empty();
  • 42. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 42
  • 43. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 43 auto oldIt = oldCookies.begin(); auto newIt = newCookies.begin(); std::vector<std::pair<Cookie, int>> diff; 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 Ошибка. Должно быть && Sean Parent: C++ Seasoning (no raw loops)
  • 44. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 44
  • 45. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 45 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));
  • 46. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 46 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));
  • 47. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 47 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; }
  • 48. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 48 bool doCompare(const Bakery& oldBakery, const Bakery& newBakery) { std::vector<Cookie> oldCookies = collectSortedCookies(oldBakery); std::vector<Cookie> newCookies = collectSortedCookies(newBakery); return lostCookies.empty() && appearedCookies.empty(); } 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; }
  • 49. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 49 bool doCompare(const Bakery* oldBakery, const Bakery* newBakery) { if (!oldBakery || !newBakery) { return false; } std::vector<Cookie> oldCookies; std::vector<Cookie> newCookies; 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(); std::vector<std::pair<Cookie, int>> diff; 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) { std::vector<Cookie> oldCookies = collectSortedCookies(oldBakery); std::vector<Cookie> newCookies = collectSortedCookies(newBakery); 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; } return lostCookies.empty() && appearedCookies.empty(); }
  • 50. Код, использующий стандартные алгоритмы и контейнеры:  Короче  Проще  Надёжнее  Обычно эффективнее  Проще переиспользовать  Не привязан к конкретной платформе "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 50
  • 51. И ещё немного по теме… "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 51
  • 52. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 52 struct Cookie { double weight; double volume; std::string name; int tastiness; auto rank() const { return std::tie(tastiness, weight, volume, name); } };
  • 53. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 53 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); } };
  • 54. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 54 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)); } };
  • 55. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 55 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)); } };
  • 56. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 56 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; }
  • 57. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 57 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));
  • 58. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 58 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; // was "lostCookies.empty() && appearedCookies.empty()"
  • 59. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 59 auto f = [](int x) { std::cout << x; }; auto it = boost::make_function_output_iterator(f); decltype(it) it2 = it; // Ok, copied it2 = it; // Does not compile, cannot assign! std::function<void(int)> f = [](int x) { std::cout << x; }; auto it = boost::make_function_output_iterator(f); decltype(it) it2 = it; // Ok, copied it2 = it; // Ok, iterator holds an std::function instance auto f = [](int x) { std::cout << x; }; auto it = boost::make_function_output_iterator(std::ref(f)); decltype(it) it2 = it; // Ok, copied it2 = it; // Ok, iterator holds a reference auto f = +[](int x) { std::cout << x; }; auto it = boost::make_function_output_iterator(f); decltype(it) it2 = it; // Ok, copied it2 = it; // Ok, note the plus before [], it triggers special C++ magic Resolving ambiguous overload on function pointer and std::function for a lambda using + boost::function_output_iterator constructed from lambda function is not assignable
  • 60. Советы:  Мыслите на высоком уровне  Код должен ясно выражать намерение  Знайте свои инструменты и используйте их к месту "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 60 // references // auto variables // auto function return type // move semantics // lambda functions operator<(); 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(); std::function<>
  • 61.  Мыслите на высоком уровне  Код должен ясно выражать намерение  Знайте свои инструменты и используйте их к месту "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 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(); std::function<> Спасибо за внимание! // references // auto variables // auto function return type // move semantics // lambda functions operator<(); std::make_tuple(); std::tie(); std::ref(); 61
  • 62. "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 62 compareRanked(Cookie const&, Cookie const&): movl 16(%rsi), %edx cmpl %edx, 16(%rdi) movl $1, %eax jl .L2 movl $0, %eax jg .L2 movsd (%rdi), %xmm1 movl $1, %eax movsd (%rsi), %xmm0 ucomisd %xmm1, %xmm0 ja .L2 xorl %eax, %eax ucomisd %xmm0, %xmm1 ja .L2 movsd 8(%rsi), %xmm0 ucomisd 8(%rdi), %xmm0 seta %al .L2: rep ret compareDirect(Cookie const&, Cookie const&): movl 16(%rsi), %eax cmpl %eax, 16(%rdi) je .L9 setl %al ret .L9: movsd (%rdi), %xmm0 movsd (%rsi), %xmm1 ucomisd %xmm1, %xmm0 jp .L13 jne .L13 movsd 8(%rsi), %xmm0 ucomisd 8(%rdi), %xmm0 seta %al ret .L13: ucomisd %xmm0, %xmm1 seta %al ret
  • 63. Ссылки  Which boost features overlap with C++11?  In-depth: Functional programming in C++  Implementing comparison operators via 'tuple' and 'tie', a good idea?  Sean Parent: C++ Seasoning (no raw loops)  boost::function_output_iterator constructed from lambda function is not assignable  Resolving ambiguous overload on function pointer and std::function for a lambda using + "Повседневный С++: boost и STL", Михаил Матросов, C++ Russia 2016 63

Editor's Notes

  1. Разрабатываю на С++ больше 10 лет, занимался обработкой изображений и 3D графикой. В настоящий момент технический менеджер в компании Align Technology. Это международная компания, производитель медицинского оборудования для нужд ортодонтии. Использует ПО, разработанную на С++. Я занимаюсь поддержкой и развитием 3D CAD приложения для планирования ортодонтического лечения. Также улучшаю качество кода и процесс разработки.
  2. Образ С++
  3. По поводу фичей, взятых из boost: http://stackoverflow.com/q/8851670/261217
  4. Исходный текст функции.
  5. Цель
  6. Посмотрим на указатели
  7. Используем ссылки
  8. Посмотрим на вызов collectCookies
  9. Убедимся, что он инициализирует вектор печенек
  10. Будем передавать его по значению
  11. Посмотрим на функцию compareCookies
  12. Посмотрим на прототип функции compareCookies
  13. Используем operator<. Никто не будет сравнивать значения с помощью вызова функции. Ну, если вы не пишете на Java.
  14. Вернёмся к коду основной функции
  15. Используем прямое сравнение
  16. Вернёмся к оператору сравнения
  17. Используем std::tuple для лексикографического сравнения
  18. Посмотрим ещё раз на сам тип Cookie
  19. Используем std::tie, чтобы не копировать std::string лишний раз Кроме того, посмотрим по дублирование списка членов
  20. Используем функцию rank(), чтобы не дублировать список членов
  21. Добавим комментарий с явным типом возвращаемого значения
  22. Объявим operator== по аналогии
  23. Посмотрим на два вызова std::sort
  24. Посмотрим на два вызова std::sort
  25. Устраним дублирование: уберём std::sort в collectCookies. Для наглядности переименуем его в collectSortedCookies.
  26. Посмотрим на явный конструктор std::pair
  27. Используем std::make_pair
  28. Используем uniform initialization
  29. Используем emplace_back()
  30. Посмотрим на цикл вывода
  31. Добавим оператора вывода в поток для печеньки
  32. Посмотрим на конструкцию вывода
  33. Заменим на эквивалентный вызов empty()
  34. Начинаем догадываться, что всё это значит. По этому поводу пишем юнит-тесты. Находим баг.
  35. Используем готовый алгоритм. Потом обращаем внимание, что неудобно писать много раз begin()/end().
  36. Используем аналог из boost::range
  37. Добавляем код с выводом. Свой вывод для пропавших и появившихся печенек.
  38. Добавляем код с выводом. Свой вывод для пропавших и появившихся печенек. Понимаем, что вывод – это всё, что нам нужно.
  39. Цель достигнута!
  40. Сейчас ещё чуть-чуть кода и котик, чтобы вы не расстраивались.
  41. Небольшой бонус относительно std::tie и std::make_tuple. Вспомним определение метода rank().
  42. Что если в вычислении ранка будут участвовать не только поля класса? Код просто не скомпилируется.
  43. Придётся вернуться к make_tuple(), но чтобы не копировать строку каждый раз, обернём её в std::reference_wrapper.
  44. Явно укажем выведенный тип.
  45. Взглянем ещё раз на тело функции. Осознаем, что у нас нет нужды сохранять множества в явном виде.
  46. Заиспользуем boost::function_output_iterator.
  47. Поскольку контейнеров в явном виде больше нет, придётся изменить способ вычисления возвращаемого значения. Есть ли проблемы с boost::make_function_output_iterator? Код может не скомпилироваться, т.к. итератор хранит предикат по значению, а у замыкания удалён оператор присваивания. Следовательно, получившийся итератор нельзя присваивать, и формально он не удовлетворяет концепту Iterator.
  48. Есть разные способы исправить итератор.
  49. Ассемблерный код для двух функций сравнения: с использованием метода rank() – compareRanked, и с использованием цепочки if’ов – compareDirect. Здесь из класса Cookie было исключено строковое поле name, чтобы не загромождать вывод. Скомпилировано x86 gcc 5.3.0 -std=c++14 -O2