SlideShare uma empresa Scribd logo
1 de 63
Повседневный С++: 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

Mais conteúdo relacionado

Mais procurados

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 189Mahmoud 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 212Mahmoud 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 189Mahmoud Samir Fayed
 
Node.js and angular js
Node.js and angular jsNode.js and angular js
Node.js and angular jsHyungKuIm
 
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 185Mahmoud 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 196Mahmoud 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 181Mahmoud Samir Fayed
 
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 84Mahmoud 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 180Mahmoud Samir Fayed
 

Mais procurados (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
 

Destaque

Повседневный С++: алгоритмы и итераторы
Повседневный С++: алгоритмы и итераторы Повседневный С++: алгоритмы и итераторы
Повседневный С++: алгоритмы и итераторы corehard_by
 
Антон Бикинеев, Reflection in C++Next
Антон Бикинеев,  Reflection in C++NextАнтон Бикинеев,  Reflection in C++Next
Антон Бикинеев, Reflection in C++NextSergey Platonov
 
Догнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_castДогнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_castRoman 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 itSergey Platonov
 
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017Mikhail 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
 
Григорий Демченко, Универсальный адаптер
Григорий Демченко, Универсальный адаптерГригорий Демченко, Универсальный адаптер
Григорий Демченко, Универсальный адаптер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++ и JavascriptSergey Platonov
 
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловПолухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловSergey Platonov
 

Destaque (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++ велосипедостроение для профессионалов
 

Semelhante a Михаил Матросов, Повседневный С++: 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 MongoDBMongoDB
 
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 202Mahmoud 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 189Mahmoud Samir Fayed
 
2011 nri-pratiques tests-avancees
2011 nri-pratiques tests-avancees2011 nri-pratiques tests-avancees
2011 nri-pratiques tests-avanceesNathaniel 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 196Mahmoud 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 MongoDBMongoDB
 
Ogdc 2013 lets remake the wheel
Ogdc 2013 lets remake the wheelOgdc 2013 lets remake the wheel
Ogdc 2013 lets remake the wheelSon Aris
 
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 Hungogdc
 
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 196Mahmoud 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 31Mahmoud Samir Fayed
 
Blockchain com JavaScript
Blockchain com JavaScriptBlockchain com JavaScript
Blockchain com JavaScriptBeto 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 MVCpootsbook
 
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 202Mahmoud 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 180Mahmoud 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 31Mahmoud Samir Fayed
 
NoSQL meets Microservices - Michael Hackstein
NoSQL meets Microservices - Michael HacksteinNoSQL meets Microservices - Michael Hackstein
NoSQL meets Microservices - Michael Hacksteindistributed matters
 

Semelhante a Михаил Матросов, Повседневный С++: 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
 
Ogdc 2013 lets remake the wheel
Ogdc 2013 lets remake the wheelOgdc 2013 lets remake the wheel
Ogdc 2013 lets remake the wheel
 
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
 
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
 

Mais de 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.ioSergey Platonov
 
Григорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизацияГригорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизацияSergey Platonov
 
Антон Полухин. C++17
Антон Полухин. C++17Антон Полухин. C++17
Антон Полухин. C++17Sergey Platonov
 
Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++Sergey Platonov
 
Денис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на Qt
Денис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на QtДенис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на Qt
Денис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на QtSergey Platonov
 
Алексей Кутумов, Coroutines everywhere
Алексей Кутумов, Coroutines everywhereАлексей Кутумов, Coroutines everywhere
Алексей Кутумов, Coroutines everywhereSergey 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
 

Mais de 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 для С++
 

Último

CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️anilsa9823
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerThousandEyes
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsAndolasoft Inc
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comFatema Valibhai
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...gurkirankumar98700
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxComplianceQuest1
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 

Último (20)

CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Exploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the ProcessExploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the Process
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 

Михаил Матросов, Повседневный С++: 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

Notas do Editor

  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