SlideShare a Scribd company logo
1 of 57
Повседневный С++: boost и STL
Михаил Матросов
mikhail.matrosov@gmail.com
mmatrosov@aligntech.com
1
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 2
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 3
С++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", Михаил Матросов, CoreHard C++ Conf 2016 4
High level:
 Парадигма RAII и исключения (exceptions)
 Алгоритмы и контейнеры STL и boost
 Семантика перемещения
 λ-функции
 Классы и конструкторы
 Простые шаблоны
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 5
Expert level:
 Операторы new/delete, владеющие
указатели
 Пользовательские операции копирования
и перемещения
 Пользовательские деструкторы
 Закрытое, защищённое, ромбовидное,
виртуальное наследование
 Шаблонная магия, SFINAE
 Все функции языка Си, препроцессор
 «Голые» циклы
Классический слайд с телом и заголовком
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 6
bool doCompare(const Bakery* oldBakery, const Bakery* newBakery)
{
if (!oldBakery || !newBakery)
{
return false;
}
std::vector<Cookie> oldCookies;
std::vector<Cookie> newCookies;
std::vector<std::pair<Cookie, int>> diff;
collectCookies(*oldBakery, oldCookies);
collectCookies(*newBakery, newCookies);
std::sort(oldCookies.begin(), oldCookies.end(), compareCookies);
std::sort(newCookies.begin(), newCookies.end(), compareCookies);
auto oldIt = oldCookies.begin();
auto newIt = newCookies.begin();
while ((oldIt != oldCookies.end()) || (newIt != newCookies.end()))
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 7
bool doCompare(const Bakery* oldBakery, const Bakery* newBakery)
{
if (!oldBakery || !newBakery)
{
return false;
}
std::vector<Cookie> oldCookies;
std::vector<Cookie> newCookies;
std::vector<std::pair<Cookie, int>> diff;
collectCookies(*oldBakery, oldCookies);
collectCookies(*newBakery, newCookies);
std::sort(oldCookies.begin(), oldCookies.end(), compareCookies);
std::sort(newCookies.begin(), newCookies.end(), compareCookies);
auto oldIt = oldCookies.begin();
auto newIt = newCookies.begin();
while ((oldIt != oldCookies.end()) || (newIt != newCookies.end()))
{
if (compareCookies(*oldIt, *newIt))
{
diff.push_back(std::pair<Cookie, int>(*oldIt, 1));
++oldIt;
}
else if (compareCookies(*newIt, *oldIt))
{
diff.push_back(std::pair<Cookie, int>(*newIt, 2));
++newIt;
}
else
{
++oldIt;
++newIt;
}
}
if (oldIt != oldCookies.end())
{
for (; oldIt < oldCookies.end(); oldIt++)
{
diff.push_back(std::pair<Cookie, int>(*oldIt, 1));
}
}
if (newIt != newCookies.end())
{
for (; newIt < newCookies.end(); newIt++)
{
diff.push_back(std::pair<Cookie, int>(*newIt, 2));
}
}
for (const auto& item : diff)
{
std::cout << "Bakery #" << item.second <<
" has a different cookie "" << item.first.name <<
"" (weight=" << item.first.weight <<
", volume=" << item.first.volume <<
", tastiness=" << item.first.tastiness << ")." << std::endl;
}
if (diff.size() > 0)
return false;
return true;
}
bool doCompare(const Bakery& oldBakery, const Bakery& newBakery)
{
auto oldCookies = collectSortedCookies(oldBakery);
auto newCookies = collectSortedCookies(newBakery);
auto reportLost = [](const Cookie& cookie) {
std::cout << "We've lost a friend: " << cookie << "." << std::endl;
};
auto reportAppeared = [](const Cookie& cookie) {
std::cout << "We got a new friend: " << cookie << "." << std::endl;
};
boost::range::set_difference(oldCookies, newCookies,
boost::make_function_output_iterator(reportLost));
boost::range::set_difference(newCookies, oldCookies,
boost::make_function_output_iterator(reportAppeared));
return oldCookies == newCookies;
}
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 8
bool doCompare(const Bakery* oldBakery, const Bakery* newBakery)
{
if (!oldBakery || !newBakery)
{
return false;
}
std::vector<Cookie> oldCookies;
std::vector<Cookie> newCookies;
std::vector<std::pair<Cookie, int>> diff;
collectCookies(*oldBakery, oldCookies);
collectCookies(*newBakery, newCookies);
// ...
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 9
bool doCompare(const Bakery& oldBakery, const Bakery& newBakery)
{
std::vector<Cookie> oldCookies;
std::vector<Cookie> newCookies;
std::vector<std::pair<Cookie, int>> diff;
collectCookies(oldBakery, oldCookies);
collectCookies(newBakery, newCookies);
// ...
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 10
bool doCompare(const Bakery& oldBakery, const Bakery& newBakery)
{
std::vector<Cookie> oldCookies;
std::vector<Cookie> newCookies;
collectCookies(oldBakery, oldCookies);
collectCookies(newBakery, newCookies);
// ...
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 11
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 12
void collectCookies(const Bakery& bakery, std::vector<Cookie>& o_cookies);
bool doCompare(const Bakery& oldBakery, const Bakery& newBakery)
{
std::vector<Cookie> oldCookies;
std::vector<Cookie> newCookies;
collectCookies(oldBakery, oldCookies);
collectCookies(newBakery, newCookies);
// ...
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 13
std::vector<Cookie> collectCookies(const Bakery& bakery);
bool doCompare(const Bakery& oldBakery, const Bakery& newBakery)
{
std::vector<Cookie> oldCookies = collectCookies(oldBakery);
std::vector<Cookie> newCookies = collectCookies(newBakery);
// ...
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 14
λλ
=:
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 15
bool doCompare(const Bakery& oldBakery, const Bakery& newBakery)
{
std::vector<Cookie> oldCookies = collectCookies(oldBakery);
std::vector<Cookie> newCookies = collectCookies(newBakery);
std::sort(oldCookies.begin(), oldCookies.end());
std::sort(newCookies.begin(), newCookies.end());
// ...
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 16
std::vector<Cookie> collectCookies(const Bakery& bakery)
{
std::vector<Cookie> cookies;
// ...
// ...
return cookies;
}
bool doCompare(const Bakery& oldBakery, const Bakery& newBakery)
{
std::vector<Cookie> oldCookies = collectCookies(oldBakery);
std::vector<Cookie> newCookies = collectCookies(newBakery);
std::sort(oldCookies.begin(), oldCookies.end());
std::sort(newCookies.begin(), newCookies.end());
// ...
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 17
std::vector<Cookie> collectSortedCookies(const Bakery& bakery)
{
std::vector<Cookie> cookies;
// ...
std::sort(cookies.begin(), cookies.end());
return cookies;
}
bool doCompare(const Bakery& oldBakery, const Bakery& newBakery)
{
std::vector<Cookie> oldCookies = collectSortedCookies(oldBakery);
std::vector<Cookie> newCookies = collectSortedCookies(newBakery);
// ...
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 18
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 19
// ...
std::sort(oldCookies.begin(), oldCookies.end(), compareCookies);
std::sort(newCookies.begin(), newCookies.end(), compareCookies);
auto oldIt = oldCookies.begin();
auto newIt = newCookies.begin();
while ((oldIt != oldCookies.end()) || (newIt != newCookies.end()))
{
if (compareCookies(*oldIt, *newIt))
{
diff.push_back(std::pair<Cookie, int>(*oldIt, 1));
++oldIt;
}
else if (compareCookies(*newIt, *oldIt))
{
// ...
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 20
struct Cookie
{
double weight;
double volume;
std::string name;
int tastiness;
};
bool compareCookies(const Cookie& a, const Cookie& b)
{
if (a.tastiness != b.tastiness)
return a.tastiness < b.tastiness;
if (a.weight != b.weight)
return a.weight < b.weight;
if (a.volume != b.volume)
return a.volume < b.volume;
return a.name < b.name;
}
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 21
struct Cookie
{
double weight;
double volume;
std::string name;
int tastiness;
};
bool operator<(const Cookie& a, const Cookie& b)
{
if (a.tastiness != b.tastiness)
return a.tastiness < b.tastiness;
if (a.weight != b.weight)
return a.weight < b.weight;
if (a.volume != b.volume)
return a.volume < b.volume;
return a.name < b.name;
}
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 22
// ...
std::sort(oldCookies.begin(), oldCookies.end(), compareCookies);
std::sort(newCookies.begin(), newCookies.end(), compareCookies);
auto oldIt = oldCookies.begin();
auto newIt = newCookies.begin();
while ((oldIt != oldCookies.end()) || (newIt != newCookies.end()))
{
if (compareCookies(*oldIt, *newIt))
{
diff.push_back(std::pair<Cookie, int>(*oldIt, 1));
++oldIt;
}
else if (compareCookies(*newIt, *oldIt))
{
// ...
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 23
// ...
std::sort(oldCookies.begin(), oldCookies.end());
std::sort(newCookies.begin(), newCookies.end());
auto oldIt = oldCookies.begin();
auto newIt = newCookies.begin();
while ((oldIt != oldCookies.end()) || (newIt != newCookies.end()))
{
if (*oldIt < *newIt)
{
diff.push_back(std::pair<Cookie, int>(*oldIt, 1));
++oldIt;
}
else if (*newIt < *oldIt)
{
// ...
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 24
bool operator<(const Cookie& a, const Cookie& b)
{
if (a.tastiness != b.tastiness)
return a.tastiness < b.tastiness;
if (a.weight != b.weight)
return a.weight < b.weight;
if (a.volume != b.volume)
return a.volume < b.volume;
return a.name < b.name;
}
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 25
bool operator<(const Cookie& a, const Cookie& b)
{
return std::make_tuple(a.tastiness, a.weight, a.volume, a.name) <
std::make_tuple(b.tastiness, b.weight, b.volume, b.name);
}
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 26
struct Cookie
{
double weight;
double volume;
std::string name;
int tastiness;
};
bool operator<(const Cookie& a, const Cookie& b)
{
return std::make_tuple(a.tastiness, a.weight, a.volume, a.name) <
std::make_tuple(b.tastiness, b.weight, b.volume, b.name);
}
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 27
struct Cookie
{
double weight;
double volume;
std::string name;
int tastiness;
};
bool operator<(const Cookie& a, const Cookie& b)
{
return std::tie(a.tastiness, a.weight, a.volume, a.name) <
std::tie(b.tastiness, b.weight, b.volume, b.name);
}
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 28
struct Cookie
{
double weight;
double volume;
std::string name;
int tastiness;
auto rank() const
{
return std::tie(tastiness, weight, volume, name);
}
bool operator<(const Cookie& rhs) const
{
return rank() < rhs.rank();
}
};
См. http://stackoverflow.com/q/6218812/261217
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 29
struct Cookie
{
double weight;
double volume;
std::string name;
int tastiness;
auto rank() const // -> std::tuple<const int&, const double&,
{ const double&, const std::string&>
return std::tie(tastiness, weight, volume, name);
}
bool operator<(const Cookie& rhs) const
{
return rank() < rhs.rank();
}
};
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 30
struct Cookie
{
double weight;
double volume;
std::string name;
int tastiness;
auto rank() const // -> std::tuple<const int&, const double&,
{ const double&, const std::string&>
return std::tie(tastiness, weight, volume, name);
}
bool operator<(const Cookie& rhs) const
{
return rank() < rhs.rank();
}
bool operator==(const Cookie& rhs) const
{
return rank() == rhs.rank();
}
};
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 31
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 32
std::vector<std::pair<Cookie, int>> diff;
// ...
if (*oldIt < *newIt)
{
diff.push_back(std::pair<Cookie, int>(*oldIt, 1));
++oldIt;
}
else if (*newIt < *oldIt)
{
diff.push_back(std::pair<Cookie, int>(*newIt, 2));
++newIt;
}
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 33
std::vector<std::pair<Cookie, int>> diff;
// ...
if (*oldIt < *newIt)
{
diff.push_back(std::make_pair(*oldIt, 1));
++oldIt;
}
else if (*newIt < *oldIt)
{
diff.push_back(std::make_pair(*newIt, 2));
++newIt;
}
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 34
std::vector<std::pair<Cookie, int>> diff;
// ...
if (*oldIt < *newIt)
{
diff.emplace_back(*oldIt, 1);
++oldIt;
}
else if (*newIt < *oldIt)
{
diff.emplace_back(*newIt, 2);
++newIt;
}
for (const auto& item : diff) // item is std::pair<Cookie, int>
{
std::cout << "Bakery #" << item.second <<
" has a different cookie "" << item.first.name <<
"" (weight=" << item.first.weight <<
", volume=" << item.first.volume <<
", tastiness=" << item.first.tastiness << ")." << std::endl;
}
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 35
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 36
for (const auto& item : diff) // item is std::pair<Cookie, int>
{
std::cout << "Bakery #" << item.second <<
" has a different cookie " << item.first << "." << std::endl;
}
std::ostream& operator<<(std::ostream& stream, const Cookie& cookie)
{
return stream << """ << cookie.name <<
"" (weight=" << cookie.weight <<
", volume=" << cookie.volume <<
", tastiness=" << cookie.tastiness << ")";
}
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 37
if (diff.size() > 0)
return false;
return true;
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 38
return diff.empty();
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 39
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 40
std::vector<std::pair<Cookie, int>> diff;
auto oldIt = oldCookies.begin();
auto newIt = newCookies.begin();
while ((oldIt != oldCookies.end()) || (newIt != newCookies.end()))
{
if (*oldIt < *newIt)
{
diff.emplace_back(*oldIt, 1);
++oldIt;
}
else if (*newIt < *oldIt)
{
diff.emplace_back(*newIt, 2);
++newIt;
}
else
{
++oldIt;
++newIt;
}
}
for (; oldIt != oldCookies.end(); oldIt++)
{
diff.emplace_back(*oldIt, 1);
}
for (; newIt != newCookies.end(); newIt++)
{
diff.emplace_back(*newIt, 2);
}
1 2 5 7 8 9
1 3 5 6 9
2 7 83 6
oldCookies
newCookies
diff
Ошибка. Должно быть &&
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 41
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 42
std::vector<Cookie> lostCookies;
std::set_difference(oldCookies.begin(), oldCookies.end(),
newCookies.begin(), newCookies.end(),
std::back_inserter(lostCookies));
std::vector<Cookie> appearedCookies;
std::set_difference(newCookies.begin(), newCookies.end(),
oldCookies.begin(), oldCookies.end(),
std::back_inserter(appearedCookies));
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 43
std::vector<Cookie> lostCookies;
boost::range::set_difference(oldCookies, newCookies,
std::back_inserter(lostCookies));
std::vector<Cookie> appearedCookies;
boost::range::set_difference(newCookies, oldCookies,
std::back_inserter(appearedCookies));
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 44
std::vector<Cookie> lostCookies;
boost::range::set_difference(oldCookies, newCookies,
std::back_inserter(lostCookies));
std::vector<Cookie> appearedCookies;
boost::range::set_difference(newCookies, oldCookies,
std::back_inserter(appearedCookies));
for (const auto& cookie : lostCookies)
{
std::cout << "We've lost a friend: " << cookie << "." << std::endl;
}
for (const auto& cookie : appearedCookies)
{
std::cout << "We got a new friend: " << cookie << "." << std::endl;
}
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 45
auto reportLost = [](const Cookie& cookie) {
std::cout << "We've lost a friend: " << cookie << "." << std::endl;
};
auto reportAppeared = [](const Cookie& cookie) {
std::cout << "We got a new friend: " << cookie << "." << std::endl;
};
boost::range::set_difference(oldCookies, newCookies,
boost::make_function_output_iterator(reportLost));
boost::range::set_difference(newCookies, oldCookies,
boost::make_function_output_iterator(reportAppeared));
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 46
bool doCompare(const Bakery& oldBakery, const Bakery& newBakery)
{
std::vector<Cookie> oldCookies = collectSortedCookies(oldBakery);
std::vector<Cookie> newCookies = collectSortedCookies(newBakery);
auto reportLost = [](const Cookie& cookie) {
std::cout << "We've lost a friend: " << cookie << "." << std::endl;
};
auto reportAppeared = [](const Cookie& cookie) {
std::cout << "We got a new friend: " << cookie << "." << std::endl;
};
boost::range::set_difference(oldCookies, newCookies,
boost::make_function_output_iterator(reportLost));
boost::range::set_difference(newCookies, oldCookies,
boost::make_function_output_iterator(reportAppeared));
return oldCookies == newCookies;
}
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 47
bool doCompare(const Bakery& oldBakery, const Bakery& newBakery)
{
auto oldCookies = collectSortedCookies(oldBakery);
auto newCookies = collectSortedCookies(newBakery);
auto reportLost = [](const Cookie& cookie) {
std::cout << "We've lost a friend: " << cookie << "." << std::endl;
};
auto reportAppeared = [](const Cookie& cookie) {
std::cout << "We got a new friend: " << cookie << "." << std::endl;
};
boost::range::set_difference(oldCookies, newCookies,
boost::make_function_output_iterator(reportLost));
boost::range::set_difference(newCookies, oldCookies,
boost::make_function_output_iterator(reportAppeared));
return oldCookies == newCookies;
}
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 48
bool doCompare(const Bakery* oldBakery, const Bakery* newBakery)
{
if (!oldBakery || !newBakery)
{
return false;
}
std::vector<Cookie> oldCookies;
std::vector<Cookie> newCookies;
std::vector<std::pair<Cookie, int>> diff;
collectCookies(*oldBakery, oldCookies);
collectCookies(*newBakery, newCookies);
std::sort(oldCookies.begin(), oldCookies.end(), compareCookies);
std::sort(newCookies.begin(), newCookies.end(), compareCookies);
auto oldIt = oldCookies.begin();
auto newIt = newCookies.begin();
while ((oldIt != oldCookies.end()) || (newIt != newCookies.end()))
{
if (compareCookies(*oldIt, *newIt))
{
diff.push_back(std::pair<Cookie, int>(*oldIt, 1));
++oldIt;
}
else if (compareCookies(*newIt, *oldIt))
{
diff.push_back(std::pair<Cookie, int>(*newIt, 2));
++newIt;
}
else
{
++oldIt;
++newIt;
}
}
if (oldIt != oldCookies.end())
{
for (; oldIt < oldCookies.end(); oldIt++)
{
diff.push_back(std::pair<Cookie, int>(*oldIt, 1));
}
}
if (newIt != newCookies.end())
{
for (; newIt < newCookies.end(); newIt++)
{
diff.push_back(std::pair<Cookie, int>(*newIt, 2));
}
}
for (const auto& item : diff)
{
std::cout << "Bakery #" << item.second <<
" has a different cookie "" << item.first.name <<
"" (weight=" << item.first.weight <<
", volume=" << item.first.volume <<
", tastiness=" << item.first.tastiness << ")." << std::endl;
}
if (diff.size() > 0)
return false;
return true;
}
bool doCompare(const Bakery& oldBakery, const Bakery& newBakery)
{
auto oldCookies = collectSortedCookies(oldBakery);
auto newCookies = collectSortedCookies(newBakery);
auto reportLost = [](const Cookie& cookie) {
std::cout << "We've lost a friend: " << cookie << "." << std::endl;
};
auto reportAppeared = [](const Cookie& cookie) {
std::cout << "We got a new friend: " << cookie << "." << std::endl;
};
boost::range::set_difference(oldCookies, newCookies,
boost::make_function_output_iterator(reportLost));
boost::range::set_difference(newCookies, oldCookies,
boost::make_function_output_iterator(reportAppeared));
return oldCookies == newCookies;
}
Код, использующий стандартные алгоритмы и контейнеры:
 Короче
 Проще
 Надёжнее
 Обычно эффективнее
 Проще переиспользовать
 Не привязан к конкретной платформе
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 49
И ещё немного
по теме…
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 50
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 51
struct Cookie
{
double weight;
double volume;
std::string name;
int tastiness;
auto rank() const
{
return std::tie(tastiness, weight, volume, name);
}
};
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 52
struct Cookie
{
double weight;
double volume;
std::string name;
int tastiness;
double density() const
{
return weight / volume;
}
auto rank() const
{
return std::tie(tastiness, density(), name); // Any problems here?..
}
};
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 53
struct Cookie
{
double weight;
double volume;
std::string name;
int tastiness;
double density() const
{
return weight / volume;
}
auto rank() const
{
return std::make_tuple(tastiness, density(), std::ref(name));
}
};
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 54
struct Cookie
{
double weight;
double volume;
std::string name;
int tastiness;
double density() const
{
return weight / volume;
}
auto rank() const // -> std::tuple<int, double, const std::string&>
{
return std::make_tuple(tastiness, density(), std::ref(name));
}
};
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 55
auto f = [](/* ... */) { /* ... */ };
boost::make_function_output_iterator(f) ->
boost::iterators::function_output_iterator<LambdaAnonymousType>
template <class UnaryFunction>
class function_output_iterator {
// ...
UnaryFunction m_f;
};
auto it1 = boost::make_function_output_iterator(f); // Not assignable
auto it2 = boost::make_function_output_iterator(std::ref(f)); // Assignable
Советы:
 Мыслите на высоком уровне
 Код должен ясно выражать намерение
 Знайте свои инструменты и используйте их к месту
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 56
// 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();
 Мыслите на высоком уровне
 Код должен ясно выражать намерение
 Знайте свои инструменты и используйте их к месту
"Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016
std::make_pair();
std::vector<T>::emplace_back();
std::vector<T>::empty();
operator<<();
std::back_inserter();
std::set_difference();
boost::range::set_difference();
boost::make_function_output_iterator();
Спасибо за внимание!
// references
// auto variables
// auto function return type
// move semantics
// lambda functions
operator<();
std::make_tuple();
std::tie();
std::ref();
57

More Related Content

What's hot

Mythbusting: Understanding How We Measure the Performance of MongoDB
Mythbusting: Understanding How We Measure the Performance of MongoDBMythbusting: Understanding How We Measure the Performance of MongoDB
Mythbusting: Understanding How We Measure the Performance of MongoDBMongoDB
 
The Ring programming language version 1.9 book - Part 50 of 210
The Ring programming language version 1.9 book - Part 50 of 210The Ring programming language version 1.9 book - Part 50 of 210
The Ring programming language version 1.9 book - Part 50 of 210Mahmoud Samir Fayed
 
Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015
Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015
Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015NoSQLmatters
 
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
 
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
 
MongoDB dla administratora
MongoDB dla administratora MongoDB dla administratora
MongoDB dla administratora 3camp
 
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.5.2 book - Part 52 of 181
The Ring programming language version 1.5.2 book - Part 52 of 181The Ring programming language version 1.5.2 book - Part 52 of 181
The Ring programming language version 1.5.2 book - Part 52 of 181Mahmoud Samir Fayed
 
The Ring programming language version 1.6 book - Part 66 of 189
The Ring programming language version 1.6 book - Part 66 of 189The Ring programming language version 1.6 book - Part 66 of 189
The Ring programming language version 1.6 book - Part 66 of 189Mahmoud Samir Fayed
 
Data analysis and visualization with mongo db [mongodb world 2016]
Data analysis and visualization with mongo db [mongodb world 2016]Data analysis and visualization with mongo db [mongodb world 2016]
Data analysis and visualization with mongo db [mongodb world 2016]Alexander Hendorf
 
The Ring programming language version 1.7 book - Part 57 of 196
The Ring programming language version 1.7 book - Part 57 of 196The Ring programming language version 1.7 book - Part 57 of 196
The Ring programming language version 1.7 book - Part 57 of 196Mahmoud Samir Fayed
 
The Ring programming language version 1.8 book - Part 59 of 202
The Ring programming language version 1.8 book - Part 59 of 202The Ring programming language version 1.8 book - Part 59 of 202
The Ring programming language version 1.8 book - Part 59 of 202Mahmoud Samir Fayed
 
The Ring programming language version 1.5.1 book - Part 27 of 180
The Ring programming language version 1.5.1 book - Part 27 of 180The Ring programming language version 1.5.1 book - Part 27 of 180
The Ring programming language version 1.5.1 book - Part 27 of 180Mahmoud Samir Fayed
 
Operational Intelligence with MongoDB Webinar
Operational Intelligence with MongoDB WebinarOperational Intelligence with MongoDB Webinar
Operational Intelligence with MongoDB WebinarMongoDB
 

What's hot (20)

Mythbusting: Understanding How We Measure the Performance of MongoDB
Mythbusting: Understanding How We Measure the Performance of MongoDBMythbusting: Understanding How We Measure the Performance of MongoDB
Mythbusting: Understanding How We Measure the Performance of MongoDB
 
Pemrograman visual
Pemrograman visualPemrograman visual
Pemrograman visual
 
The Ring programming language version 1.9 book - Part 50 of 210
The Ring programming language version 1.9 book - Part 50 of 210The Ring programming language version 1.9 book - Part 50 of 210
The Ring programming language version 1.9 book - Part 50 of 210
 
Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015
Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015
Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015
 
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
 
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
 
MongoDB dla administratora
MongoDB dla administratora MongoDB dla administratora
MongoDB dla administratora
 
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
 
Functions
FunctionsFunctions
Functions
 
Ac2
Ac2Ac2
Ac2
 
The Ring programming language version 1.5.2 book - Part 52 of 181
The Ring programming language version 1.5.2 book - Part 52 of 181The Ring programming language version 1.5.2 book - Part 52 of 181
The Ring programming language version 1.5.2 book - Part 52 of 181
 
Ocr code
Ocr codeOcr code
Ocr code
 
The Ring programming language version 1.6 book - Part 66 of 189
The Ring programming language version 1.6 book - Part 66 of 189The Ring programming language version 1.6 book - Part 66 of 189
The Ring programming language version 1.6 book - Part 66 of 189
 
Data analysis and visualization with mongo db [mongodb world 2016]
Data analysis and visualization with mongo db [mongodb world 2016]Data analysis and visualization with mongo db [mongodb world 2016]
Data analysis and visualization with mongo db [mongodb world 2016]
 
The Ring programming language version 1.7 book - Part 57 of 196
The Ring programming language version 1.7 book - Part 57 of 196The Ring programming language version 1.7 book - Part 57 of 196
The Ring programming language version 1.7 book - Part 57 of 196
 
The Ring programming language version 1.8 book - Part 59 of 202
The Ring programming language version 1.8 book - Part 59 of 202The Ring programming language version 1.8 book - Part 59 of 202
The Ring programming language version 1.8 book - Part 59 of 202
 
The Ring programming language version 1.5.1 book - Part 27 of 180
The Ring programming language version 1.5.1 book - Part 27 of 180The Ring programming language version 1.5.1 book - Part 27 of 180
The Ring programming language version 1.5.1 book - Part 27 of 180
 
openGl example
openGl exampleopenGl example
openGl example
 
Operational Intelligence with MongoDB Webinar
Operational Intelligence with MongoDB WebinarOperational Intelligence with MongoDB Webinar
Operational Intelligence with MongoDB Webinar
 
C programs
C programsC programs
C programs
 

Similar to Matrosov daily c++

Blockchain com JavaScript
Blockchain com JavaScriptBlockchain com JavaScript
Blockchain com JavaScriptBeto Muniz
 
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
 
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
 
The Ring programming language version 1.5.3 book - Part 15 of 184
The Ring programming language version 1.5.3 book - Part 15 of 184The Ring programming language version 1.5.3 book - Part 15 of 184
The Ring programming language version 1.5.3 book - Part 15 of 184Mahmoud Samir Fayed
 
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
 
QA Fes 2016. Ярослав Пернеровский. Не Jav'ой единой. Пример автоматизации тес...
QA Fes 2016. Ярослав Пернеровский. Не Jav'ой единой. Пример автоматизации тес...QA Fes 2016. Ярослав Пернеровский. Не Jav'ой единой. Пример автоматизации тес...
QA Fes 2016. Ярослав Пернеровский. Не Jav'ой единой. Пример автоматизации тес...QAFest
 
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.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
 
Будь первым
Будь первымБудь первым
Будь первым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
 
NoSQL meets Microservices - Michael Hackstein
NoSQL meets Microservices - Michael HacksteinNoSQL meets Microservices - Michael Hackstein
NoSQL meets Microservices - Michael Hacksteindistributed matters
 
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
 
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
 
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
 
Back to Basics Webinar 2 - Your First MongoDB Application
Back to  Basics Webinar 2 - Your First MongoDB ApplicationBack to  Basics Webinar 2 - Your First MongoDB Application
Back to Basics Webinar 2 - Your First MongoDB ApplicationJoe Drumgoole
 
Back to Basics Webinar 2: Your First MongoDB Application
Back to Basics Webinar 2: Your First MongoDB ApplicationBack to Basics Webinar 2: Your First MongoDB Application
Back to Basics Webinar 2: Your First MongoDB ApplicationMongoDB
 

Similar to Matrosov daily c++ (20)

Intro
IntroIntro
Intro
 
Blockchain com JavaScript
Blockchain com JavaScriptBlockchain com JavaScript
Blockchain com JavaScript
 
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
 
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
 
The Ring programming language version 1.5.3 book - Part 15 of 184
The Ring programming language version 1.5.3 book - Part 15 of 184The Ring programming language version 1.5.3 book - Part 15 of 184
The Ring programming language version 1.5.3 book - Part 15 of 184
 
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
 
QA Fes 2016. Ярослав Пернеровский. Не Jav'ой единой. Пример автоматизации тес...
QA Fes 2016. Ярослав Пернеровский. Не Jav'ой единой. Пример автоматизации тес...QA Fes 2016. Ярослав Пернеровский. Не Jav'ой единой. Пример автоматизации тес...
QA Fes 2016. Ярослав Пернеровский. Не Jav'ой единой. Пример автоматизации тес...
 
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.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.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
 
NoSQL meets Microservices - Michael Hackstein
NoSQL meets Microservices - Michael HacksteinNoSQL meets Microservices - Michael Hackstein
NoSQL meets Microservices - Michael Hackstein
 
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
 
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
 
Qtp test
Qtp testQtp test
Qtp test
 
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
 
Back to Basics Webinar 2 - Your First MongoDB Application
Back to  Basics Webinar 2 - Your First MongoDB ApplicationBack to  Basics Webinar 2 - Your First MongoDB Application
Back to Basics Webinar 2 - Your First MongoDB Application
 
Back to Basics Webinar 2: Your First MongoDB Application
Back to Basics Webinar 2: Your First MongoDB ApplicationBack to Basics Webinar 2: Your First MongoDB Application
Back to Basics Webinar 2: Your First MongoDB Application
 

More from corehard_by

C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...corehard_by
 
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...corehard_by
 
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений ОхотниковC++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотниковcorehard_by
 
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр ТитовC++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титовcorehard_by
 
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...corehard_by
 
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья ШишковC++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишковcorehard_by
 
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...corehard_by
 
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...corehard_by
 
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...corehard_by
 
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...corehard_by
 
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...corehard_by
 
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...corehard_by
 
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел ФилоновC++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филоновcorehard_by
 
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan ČukićC++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukićcorehard_by
 
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia KazakovaC++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakovacorehard_by
 
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон ПолухинC++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухинcorehard_by
 
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...corehard_by
 
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019corehard_by
 
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019corehard_by
 
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019corehard_by
 

More from corehard_by (20)

C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
 
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
 
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений ОхотниковC++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
 
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр ТитовC++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
 
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
 
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья ШишковC++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
 
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
 
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
 
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
 
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
 
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
 
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
 
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел ФилоновC++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
 
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan ČukićC++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
 
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia KazakovaC++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
 
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон ПолухинC++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
 
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
 
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
 
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
 
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
 

Recently uploaded

Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024BookNet Canada
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphNeo4j
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Unlocking the Potential of the Cloud for IBM Power Systems
Unlocking the Potential of the Cloud for IBM Power SystemsUnlocking the Potential of the Cloud for IBM Power Systems
Unlocking the Potential of the Cloud for IBM Power SystemsPrecisely
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024Neo4j
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 

Recently uploaded (20)

Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Unlocking the Potential of the Cloud for IBM Power Systems
Unlocking the Potential of the Cloud for IBM Power SystemsUnlocking the Potential of the Cloud for IBM Power Systems
Unlocking the Potential of the Cloud for IBM Power Systems
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food Manufacturing
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 

Matrosov daily c++

  • 1. Повседневный С++: boost и STL Михаил Матросов mikhail.matrosov@gmail.com mmatrosov@aligntech.com 1
  • 2. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 2
  • 3. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 3 С++17 С++11/14 С++98 С High level Expert level Modern C++
  • 4. “Within C++ is a smaller, simpler, safer language struggling to get out” Bjarne Stroustrup "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 4
  • 5. High level:  Парадигма RAII и исключения (exceptions)  Алгоритмы и контейнеры STL и boost  Семантика перемещения  λ-функции  Классы и конструкторы  Простые шаблоны "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 5 Expert level:  Операторы new/delete, владеющие указатели  Пользовательские операции копирования и перемещения  Пользовательские деструкторы  Закрытое, защищённое, ромбовидное, виртуальное наследование  Шаблонная магия, SFINAE  Все функции языка Си, препроцессор  «Голые» циклы Классический слайд с телом и заголовком
  • 6. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 6 bool doCompare(const Bakery* oldBakery, const Bakery* newBakery) { if (!oldBakery || !newBakery) { return false; } std::vector<Cookie> oldCookies; std::vector<Cookie> newCookies; std::vector<std::pair<Cookie, int>> diff; collectCookies(*oldBakery, oldCookies); collectCookies(*newBakery, newCookies); std::sort(oldCookies.begin(), oldCookies.end(), compareCookies); std::sort(newCookies.begin(), newCookies.end(), compareCookies); auto oldIt = oldCookies.begin(); auto newIt = newCookies.begin(); while ((oldIt != oldCookies.end()) || (newIt != newCookies.end()))
  • 7. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 7 bool doCompare(const Bakery* oldBakery, const Bakery* newBakery) { if (!oldBakery || !newBakery) { return false; } std::vector<Cookie> oldCookies; std::vector<Cookie> newCookies; std::vector<std::pair<Cookie, int>> diff; collectCookies(*oldBakery, oldCookies); collectCookies(*newBakery, newCookies); std::sort(oldCookies.begin(), oldCookies.end(), compareCookies); std::sort(newCookies.begin(), newCookies.end(), compareCookies); auto oldIt = oldCookies.begin(); auto newIt = newCookies.begin(); while ((oldIt != oldCookies.end()) || (newIt != newCookies.end())) { if (compareCookies(*oldIt, *newIt)) { diff.push_back(std::pair<Cookie, int>(*oldIt, 1)); ++oldIt; } else if (compareCookies(*newIt, *oldIt)) { diff.push_back(std::pair<Cookie, int>(*newIt, 2)); ++newIt; } else { ++oldIt; ++newIt; } } if (oldIt != oldCookies.end()) { for (; oldIt < oldCookies.end(); oldIt++) { diff.push_back(std::pair<Cookie, int>(*oldIt, 1)); } } if (newIt != newCookies.end()) { for (; newIt < newCookies.end(); newIt++) { diff.push_back(std::pair<Cookie, int>(*newIt, 2)); } } for (const auto& item : diff) { std::cout << "Bakery #" << item.second << " has a different cookie "" << item.first.name << "" (weight=" << item.first.weight << ", volume=" << item.first.volume << ", tastiness=" << item.first.tastiness << ")." << std::endl; } if (diff.size() > 0) return false; return true; } bool doCompare(const Bakery& oldBakery, const Bakery& newBakery) { auto oldCookies = collectSortedCookies(oldBakery); auto newCookies = collectSortedCookies(newBakery); auto reportLost = [](const Cookie& cookie) { std::cout << "We've lost a friend: " << cookie << "." << std::endl; }; auto reportAppeared = [](const Cookie& cookie) { std::cout << "We got a new friend: " << cookie << "." << std::endl; }; boost::range::set_difference(oldCookies, newCookies, boost::make_function_output_iterator(reportLost)); boost::range::set_difference(newCookies, oldCookies, boost::make_function_output_iterator(reportAppeared)); return oldCookies == newCookies; }
  • 8. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 8 bool doCompare(const Bakery* oldBakery, const Bakery* newBakery) { if (!oldBakery || !newBakery) { return false; } std::vector<Cookie> oldCookies; std::vector<Cookie> newCookies; std::vector<std::pair<Cookie, int>> diff; collectCookies(*oldBakery, oldCookies); collectCookies(*newBakery, newCookies); // ...
  • 9. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 9 bool doCompare(const Bakery& oldBakery, const Bakery& newBakery) { std::vector<Cookie> oldCookies; std::vector<Cookie> newCookies; std::vector<std::pair<Cookie, int>> diff; collectCookies(oldBakery, oldCookies); collectCookies(newBakery, newCookies); // ...
  • 10. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 10
  • 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", Михаил Матросов, CoreHard C++ Conf 2016 11
  • 12. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 12 void collectCookies(const Bakery& bakery, std::vector<Cookie>& o_cookies); bool doCompare(const Bakery& oldBakery, const Bakery& newBakery) { std::vector<Cookie> oldCookies; std::vector<Cookie> newCookies; collectCookies(oldBakery, oldCookies); collectCookies(newBakery, newCookies); // ...
  • 13. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 13 std::vector<Cookie> collectCookies(const Bakery& bakery); bool doCompare(const Bakery& oldBakery, const Bakery& newBakery) { std::vector<Cookie> oldCookies = collectCookies(oldBakery); std::vector<Cookie> newCookies = collectCookies(newBakery); // ...
  • 14. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 14 λλ =:
  • 15. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 15 bool doCompare(const Bakery& oldBakery, const Bakery& newBakery) { std::vector<Cookie> oldCookies = collectCookies(oldBakery); std::vector<Cookie> newCookies = collectCookies(newBakery); std::sort(oldCookies.begin(), oldCookies.end()); std::sort(newCookies.begin(), newCookies.end()); // ...
  • 16. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 16 std::vector<Cookie> collectCookies(const Bakery& bakery) { std::vector<Cookie> cookies; // ... // ... return cookies; } bool doCompare(const Bakery& oldBakery, const Bakery& newBakery) { std::vector<Cookie> oldCookies = collectCookies(oldBakery); std::vector<Cookie> newCookies = collectCookies(newBakery); std::sort(oldCookies.begin(), oldCookies.end()); std::sort(newCookies.begin(), newCookies.end()); // ...
  • 17. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 17 std::vector<Cookie> collectSortedCookies(const Bakery& bakery) { std::vector<Cookie> cookies; // ... std::sort(cookies.begin(), cookies.end()); return cookies; } bool doCompare(const Bakery& oldBakery, const Bakery& newBakery) { std::vector<Cookie> oldCookies = collectSortedCookies(oldBakery); std::vector<Cookie> newCookies = collectSortedCookies(newBakery); // ...
  • 18. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 18
  • 19. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 19 // ... std::sort(oldCookies.begin(), oldCookies.end(), compareCookies); std::sort(newCookies.begin(), newCookies.end(), compareCookies); auto oldIt = oldCookies.begin(); auto newIt = newCookies.begin(); while ((oldIt != oldCookies.end()) || (newIt != newCookies.end())) { if (compareCookies(*oldIt, *newIt)) { diff.push_back(std::pair<Cookie, int>(*oldIt, 1)); ++oldIt; } else if (compareCookies(*newIt, *oldIt)) { // ...
  • 20. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 20 struct Cookie { double weight; double volume; std::string name; int tastiness; }; bool compareCookies(const Cookie& a, const Cookie& b) { if (a.tastiness != b.tastiness) return a.tastiness < b.tastiness; if (a.weight != b.weight) return a.weight < b.weight; if (a.volume != b.volume) return a.volume < b.volume; return a.name < b.name; }
  • 21. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 21 struct Cookie { double weight; double volume; std::string name; int tastiness; }; bool operator<(const Cookie& a, const Cookie& b) { if (a.tastiness != b.tastiness) return a.tastiness < b.tastiness; if (a.weight != b.weight) return a.weight < b.weight; if (a.volume != b.volume) return a.volume < b.volume; return a.name < b.name; }
  • 22. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 22 // ... std::sort(oldCookies.begin(), oldCookies.end(), compareCookies); std::sort(newCookies.begin(), newCookies.end(), compareCookies); auto oldIt = oldCookies.begin(); auto newIt = newCookies.begin(); while ((oldIt != oldCookies.end()) || (newIt != newCookies.end())) { if (compareCookies(*oldIt, *newIt)) { diff.push_back(std::pair<Cookie, int>(*oldIt, 1)); ++oldIt; } else if (compareCookies(*newIt, *oldIt)) { // ...
  • 23. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 23 // ... std::sort(oldCookies.begin(), oldCookies.end()); std::sort(newCookies.begin(), newCookies.end()); auto oldIt = oldCookies.begin(); auto newIt = newCookies.begin(); while ((oldIt != oldCookies.end()) || (newIt != newCookies.end())) { if (*oldIt < *newIt) { diff.push_back(std::pair<Cookie, int>(*oldIt, 1)); ++oldIt; } else if (*newIt < *oldIt) { // ...
  • 24. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 24 bool operator<(const Cookie& a, const Cookie& b) { if (a.tastiness != b.tastiness) return a.tastiness < b.tastiness; if (a.weight != b.weight) return a.weight < b.weight; if (a.volume != b.volume) return a.volume < b.volume; return a.name < b.name; }
  • 25. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 25 bool operator<(const Cookie& a, const Cookie& b) { return std::make_tuple(a.tastiness, a.weight, a.volume, a.name) < std::make_tuple(b.tastiness, b.weight, b.volume, b.name); }
  • 26. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 26 struct Cookie { double weight; double volume; std::string name; int tastiness; }; bool operator<(const Cookie& a, const Cookie& b) { return std::make_tuple(a.tastiness, a.weight, a.volume, a.name) < std::make_tuple(b.tastiness, b.weight, b.volume, b.name); }
  • 27. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 27 struct Cookie { double weight; double volume; std::string name; int tastiness; }; bool operator<(const Cookie& a, const Cookie& b) { return std::tie(a.tastiness, a.weight, a.volume, a.name) < std::tie(b.tastiness, b.weight, b.volume, b.name); }
  • 28. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 28 struct Cookie { double weight; double volume; std::string name; int tastiness; auto rank() const { return std::tie(tastiness, weight, volume, name); } bool operator<(const Cookie& rhs) const { return rank() < rhs.rank(); } }; См. http://stackoverflow.com/q/6218812/261217
  • 29. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 29 struct Cookie { double weight; double volume; std::string name; int tastiness; auto rank() const // -> std::tuple<const int&, const double&, { const double&, const std::string&> return std::tie(tastiness, weight, volume, name); } bool operator<(const Cookie& rhs) const { return rank() < rhs.rank(); } };
  • 30. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 30 struct Cookie { double weight; double volume; std::string name; int tastiness; auto rank() const // -> std::tuple<const int&, const double&, { const double&, const std::string&> return std::tie(tastiness, weight, volume, name); } bool operator<(const Cookie& rhs) const { return rank() < rhs.rank(); } bool operator==(const Cookie& rhs) const { return rank() == rhs.rank(); } };
  • 31. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 31
  • 32. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 32 std::vector<std::pair<Cookie, int>> diff; // ... if (*oldIt < *newIt) { diff.push_back(std::pair<Cookie, int>(*oldIt, 1)); ++oldIt; } else if (*newIt < *oldIt) { diff.push_back(std::pair<Cookie, int>(*newIt, 2)); ++newIt; }
  • 33. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 33 std::vector<std::pair<Cookie, int>> diff; // ... if (*oldIt < *newIt) { diff.push_back(std::make_pair(*oldIt, 1)); ++oldIt; } else if (*newIt < *oldIt) { diff.push_back(std::make_pair(*newIt, 2)); ++newIt; }
  • 34. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 34 std::vector<std::pair<Cookie, int>> diff; // ... if (*oldIt < *newIt) { diff.emplace_back(*oldIt, 1); ++oldIt; } else if (*newIt < *oldIt) { diff.emplace_back(*newIt, 2); ++newIt; }
  • 35. for (const auto& item : diff) // item is std::pair<Cookie, int> { std::cout << "Bakery #" << item.second << " has a different cookie "" << item.first.name << "" (weight=" << item.first.weight << ", volume=" << item.first.volume << ", tastiness=" << item.first.tastiness << ")." << std::endl; } "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 35
  • 36. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 36 for (const auto& item : diff) // item is std::pair<Cookie, int> { std::cout << "Bakery #" << item.second << " has a different cookie " << item.first << "." << std::endl; } std::ostream& operator<<(std::ostream& stream, const Cookie& cookie) { return stream << """ << cookie.name << "" (weight=" << cookie.weight << ", volume=" << cookie.volume << ", tastiness=" << cookie.tastiness << ")"; }
  • 37. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 37 if (diff.size() > 0) return false; return true;
  • 38. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 38 return diff.empty();
  • 39. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 39
  • 40. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 40 std::vector<std::pair<Cookie, int>> diff; auto oldIt = oldCookies.begin(); auto newIt = newCookies.begin(); while ((oldIt != oldCookies.end()) || (newIt != newCookies.end())) { if (*oldIt < *newIt) { diff.emplace_back(*oldIt, 1); ++oldIt; } else if (*newIt < *oldIt) { diff.emplace_back(*newIt, 2); ++newIt; } else { ++oldIt; ++newIt; } } for (; oldIt != oldCookies.end(); oldIt++) { diff.emplace_back(*oldIt, 1); } for (; newIt != newCookies.end(); newIt++) { diff.emplace_back(*newIt, 2); } 1 2 5 7 8 9 1 3 5 6 9 2 7 83 6 oldCookies newCookies diff Ошибка. Должно быть &&
  • 41. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 41
  • 42. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 42 std::vector<Cookie> lostCookies; std::set_difference(oldCookies.begin(), oldCookies.end(), newCookies.begin(), newCookies.end(), std::back_inserter(lostCookies)); std::vector<Cookie> appearedCookies; std::set_difference(newCookies.begin(), newCookies.end(), oldCookies.begin(), oldCookies.end(), std::back_inserter(appearedCookies));
  • 43. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 43 std::vector<Cookie> lostCookies; boost::range::set_difference(oldCookies, newCookies, std::back_inserter(lostCookies)); std::vector<Cookie> appearedCookies; boost::range::set_difference(newCookies, oldCookies, std::back_inserter(appearedCookies));
  • 44. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 44 std::vector<Cookie> lostCookies; boost::range::set_difference(oldCookies, newCookies, std::back_inserter(lostCookies)); std::vector<Cookie> appearedCookies; boost::range::set_difference(newCookies, oldCookies, std::back_inserter(appearedCookies)); for (const auto& cookie : lostCookies) { std::cout << "We've lost a friend: " << cookie << "." << std::endl; } for (const auto& cookie : appearedCookies) { std::cout << "We got a new friend: " << cookie << "." << std::endl; }
  • 45. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 45 auto reportLost = [](const Cookie& cookie) { std::cout << "We've lost a friend: " << cookie << "." << std::endl; }; auto reportAppeared = [](const Cookie& cookie) { std::cout << "We got a new friend: " << cookie << "." << std::endl; }; boost::range::set_difference(oldCookies, newCookies, boost::make_function_output_iterator(reportLost)); boost::range::set_difference(newCookies, oldCookies, boost::make_function_output_iterator(reportAppeared));
  • 46. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 46 bool doCompare(const Bakery& oldBakery, const Bakery& newBakery) { std::vector<Cookie> oldCookies = collectSortedCookies(oldBakery); std::vector<Cookie> newCookies = collectSortedCookies(newBakery); auto reportLost = [](const Cookie& cookie) { std::cout << "We've lost a friend: " << cookie << "." << std::endl; }; auto reportAppeared = [](const Cookie& cookie) { std::cout << "We got a new friend: " << cookie << "." << std::endl; }; boost::range::set_difference(oldCookies, newCookies, boost::make_function_output_iterator(reportLost)); boost::range::set_difference(newCookies, oldCookies, boost::make_function_output_iterator(reportAppeared)); return oldCookies == newCookies; }
  • 47. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 47 bool doCompare(const Bakery& oldBakery, const Bakery& newBakery) { auto oldCookies = collectSortedCookies(oldBakery); auto newCookies = collectSortedCookies(newBakery); auto reportLost = [](const Cookie& cookie) { std::cout << "We've lost a friend: " << cookie << "." << std::endl; }; auto reportAppeared = [](const Cookie& cookie) { std::cout << "We got a new friend: " << cookie << "." << std::endl; }; boost::range::set_difference(oldCookies, newCookies, boost::make_function_output_iterator(reportLost)); boost::range::set_difference(newCookies, oldCookies, boost::make_function_output_iterator(reportAppeared)); return oldCookies == newCookies; }
  • 48. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 48 bool doCompare(const Bakery* oldBakery, const Bakery* newBakery) { if (!oldBakery || !newBakery) { return false; } std::vector<Cookie> oldCookies; std::vector<Cookie> newCookies; std::vector<std::pair<Cookie, int>> diff; collectCookies(*oldBakery, oldCookies); collectCookies(*newBakery, newCookies); std::sort(oldCookies.begin(), oldCookies.end(), compareCookies); std::sort(newCookies.begin(), newCookies.end(), compareCookies); auto oldIt = oldCookies.begin(); auto newIt = newCookies.begin(); while ((oldIt != oldCookies.end()) || (newIt != newCookies.end())) { if (compareCookies(*oldIt, *newIt)) { diff.push_back(std::pair<Cookie, int>(*oldIt, 1)); ++oldIt; } else if (compareCookies(*newIt, *oldIt)) { diff.push_back(std::pair<Cookie, int>(*newIt, 2)); ++newIt; } else { ++oldIt; ++newIt; } } if (oldIt != oldCookies.end()) { for (; oldIt < oldCookies.end(); oldIt++) { diff.push_back(std::pair<Cookie, int>(*oldIt, 1)); } } if (newIt != newCookies.end()) { for (; newIt < newCookies.end(); newIt++) { diff.push_back(std::pair<Cookie, int>(*newIt, 2)); } } for (const auto& item : diff) { std::cout << "Bakery #" << item.second << " has a different cookie "" << item.first.name << "" (weight=" << item.first.weight << ", volume=" << item.first.volume << ", tastiness=" << item.first.tastiness << ")." << std::endl; } if (diff.size() > 0) return false; return true; } bool doCompare(const Bakery& oldBakery, const Bakery& newBakery) { auto oldCookies = collectSortedCookies(oldBakery); auto newCookies = collectSortedCookies(newBakery); auto reportLost = [](const Cookie& cookie) { std::cout << "We've lost a friend: " << cookie << "." << std::endl; }; auto reportAppeared = [](const Cookie& cookie) { std::cout << "We got a new friend: " << cookie << "." << std::endl; }; boost::range::set_difference(oldCookies, newCookies, boost::make_function_output_iterator(reportLost)); boost::range::set_difference(newCookies, oldCookies, boost::make_function_output_iterator(reportAppeared)); return oldCookies == newCookies; }
  • 49. Код, использующий стандартные алгоритмы и контейнеры:  Короче  Проще  Надёжнее  Обычно эффективнее  Проще переиспользовать  Не привязан к конкретной платформе "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 49
  • 50. И ещё немного по теме… "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 50
  • 51. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 51 struct Cookie { double weight; double volume; std::string name; int tastiness; auto rank() const { return std::tie(tastiness, weight, volume, name); } };
  • 52. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 52 struct Cookie { double weight; double volume; std::string name; int tastiness; double density() const { return weight / volume; } auto rank() const { return std::tie(tastiness, density(), name); // Any problems here?.. } };
  • 53. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 53 struct Cookie { double weight; double volume; std::string name; int tastiness; double density() const { return weight / volume; } auto rank() const { return std::make_tuple(tastiness, density(), std::ref(name)); } };
  • 54. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 54 struct Cookie { double weight; double volume; std::string name; int tastiness; double density() const { return weight / volume; } auto rank() const // -> std::tuple<int, double, const std::string&> { return std::make_tuple(tastiness, density(), std::ref(name)); } };
  • 55. "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 55 auto f = [](/* ... */) { /* ... */ }; boost::make_function_output_iterator(f) -> boost::iterators::function_output_iterator<LambdaAnonymousType> template <class UnaryFunction> class function_output_iterator { // ... UnaryFunction m_f; }; auto it1 = boost::make_function_output_iterator(f); // Not assignable auto it2 = boost::make_function_output_iterator(std::ref(f)); // Assignable
  • 56. Советы:  Мыслите на высоком уровне  Код должен ясно выражать намерение  Знайте свои инструменты и используйте их к месту "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 56 // 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();
  • 57.  Мыслите на высоком уровне  Код должен ясно выражать намерение  Знайте свои инструменты и используйте их к месту "Повседневный С++: boost и STL", Михаил Матросов, CoreHard C++ Conf 2016 std::make_pair(); std::vector<T>::emplace_back(); std::vector<T>::empty(); operator<<(); std::back_inserter(); std::set_difference(); boost::range::set_difference(); boost::make_function_output_iterator(); Спасибо за внимание! // references // auto variables // auto function return type // move semantics // lambda functions operator<(); std::make_tuple(); std::tie(); std::ref(); 57

Editor's Notes

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