SlideShare a Scribd company logo
Повседневный С++: 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 MongoDB
MongoDB
 
Pemrograman visual
Pemrograman visualPemrograman visual
Pemrograman visual
Univ. State of Surabaya
 
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
Mahmoud 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 2015
NoSQLmatters
 
The Ring programming language version 1.6 book - Part 62 of 189
The Ring programming language version 1.6 book - Part 62 of 189The Ring programming language version 1.6 book - Part 62 of 189
The Ring programming language version 1.6 book - Part 62 of 189
Mahmoud Samir Fayed
 
The Ring programming language version 1.5.1 book - Part 51 of 180
The Ring programming language version 1.5.1 book - Part 51 of 180The Ring programming language version 1.5.1 book - Part 51 of 180
The Ring programming language version 1.5.1 book - Part 51 of 180
Mahmoud Samir Fayed
 
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 185
Mahmoud Samir Fayed
 
Functions
FunctionsFunctions
Functions
G.C Reddy
 
Ac2
Ac2Ac2
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
Mahmoud Samir Fayed
 
Ocr code
Ocr codeOcr code
Ocr code
wi7sonjoseph
 
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
Mahmoud 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 196
Mahmoud 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 202
Mahmoud 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 180
Mahmoud Samir Fayed
 
openGl example
openGl exampleopenGl example
openGl example
Brian Goggins
 
Operational Intelligence with MongoDB Webinar
Operational Intelligence with MongoDB WebinarOperational Intelligence with MongoDB Webinar
Operational Intelligence with MongoDB Webinar
MongoDB
 
C programs
C programsC programs
C programs
Azaj Khan
 

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++

Intro
IntroIntro
Intro
bspremo
 
Blockchain com JavaScript
Blockchain com JavaScriptBlockchain com JavaScript
Blockchain com JavaScript
Beto 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 MongoDB
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
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
Mahmoud 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 196
Mahmoud 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-avancees
Nathaniel 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 202
Mahmoud 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 31
Mahmoud Samir Fayed
 
NoSQL meets Microservices - Michael Hackstein
NoSQL meets Microservices - Michael HacksteinNoSQL meets Microservices - Michael Hackstein
NoSQL meets Microservices - Michael Hackstein
distributed matters
 
The Ring programming language version 1.6 book - Part 70 of 189
The Ring programming language version 1.6 book - Part 70 of 189The Ring programming language version 1.6 book - Part 70 of 189
The Ring programming language version 1.6 book - Part 70 of 189
Mahmoud Samir Fayed
 
The Ring programming language version 1.7 book - Part 72 of 196
The Ring programming language version 1.7 book - Part 72 of 196The Ring programming language version 1.7 book - Part 72 of 196
The Ring programming language version 1.7 book - Part 72 of 196
Mahmoud Samir Fayed
 
Qtp test
Qtp testQtp test
Qtp test
G.C Reddy
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVC
pootsbook
 
The Ring programming language version 1.8 book - Part 49 of 202
The Ring programming language version 1.8 book - Part 49 of 202The Ring programming language version 1.8 book - Part 49 of 202
The Ring programming language version 1.8 book - Part 49 of 202
Mahmoud Samir Fayed
 
The Ring programming language version 1.5.1 book - Part 64 of 180
The Ring programming language version 1.5.1 book - Part 64 of 180The Ring programming language version 1.5.1 book - Part 64 of 180
The Ring programming language version 1.5.1 book - Part 64 of 180
Mahmoud Samir Fayed
 
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
Joe 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 Application
MongoDB
 

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 Kazakova
corehard_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 2019
corehard_by
 
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
corehard_by
 
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
corehard_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

Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
saastr
 
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development ProvidersYour One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
akankshawande
 
Recommendation System using RAG Architecture
Recommendation System using RAG ArchitectureRecommendation System using RAG Architecture
Recommendation System using RAG Architecture
fredae14
 
Finale of the Year: Apply for Next One!
Finale of the Year: Apply for Next One!Finale of the Year: Apply for Next One!
Finale of the Year: Apply for Next One!
GDSC PJATK
 
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success StoryDriving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Safe Software
 
Energy Efficient Video Encoding for Cloud and Edge Computing Instances
Energy Efficient Video Encoding for Cloud and Edge Computing InstancesEnergy Efficient Video Encoding for Cloud and Edge Computing Instances
Energy Efficient Video Encoding for Cloud and Edge Computing Instances
Alpen-Adria-Universität
 
A Comprehensive Guide to DeFi Development Services in 2024
A Comprehensive Guide to DeFi Development Services in 2024A Comprehensive Guide to DeFi Development Services in 2024
A Comprehensive Guide to DeFi Development Services in 2024
Intelisync
 
Artificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopmentArtificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopment
Octavian Nadolu
 
Azure API Management to expose backend services securely
Azure API Management to expose backend services securelyAzure API Management to expose backend services securely
Azure API Management to expose backend services securely
Dinusha Kumarasiri
 
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdfHow to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
Chart Kalyan
 
Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024
Jason Packer
 
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdfMonitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Tosin Akinosho
 
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdfUnlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Malak Abu Hammad
 
GenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizationsGenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizations
kumardaparthi1024
 
June Patch Tuesday
June Patch TuesdayJune Patch Tuesday
June Patch Tuesday
Ivanti
 
dbms calicut university B. sc Cs 4th sem.pdf
dbms  calicut university B. sc Cs 4th sem.pdfdbms  calicut university B. sc Cs 4th sem.pdf
dbms calicut university B. sc Cs 4th sem.pdf
Shinana2
 
Presentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of GermanyPresentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of Germany
innovationoecd
 
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
Tatiana Kojar
 
System Design Case Study: Building a Scalable E-Commerce Platform - Hiike
System Design Case Study: Building a Scalable E-Commerce Platform - HiikeSystem Design Case Study: Building a Scalable E-Commerce Platform - Hiike
System Design Case Study: Building a Scalable E-Commerce Platform - Hiike
Hiike
 
Nordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptxNordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptx
MichaelKnudsen27
 

Recently uploaded (20)

Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
 
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development ProvidersYour One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
 
Recommendation System using RAG Architecture
Recommendation System using RAG ArchitectureRecommendation System using RAG Architecture
Recommendation System using RAG Architecture
 
Finale of the Year: Apply for Next One!
Finale of the Year: Apply for Next One!Finale of the Year: Apply for Next One!
Finale of the Year: Apply for Next One!
 
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success StoryDriving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success Story
 
Energy Efficient Video Encoding for Cloud and Edge Computing Instances
Energy Efficient Video Encoding for Cloud and Edge Computing InstancesEnergy Efficient Video Encoding for Cloud and Edge Computing Instances
Energy Efficient Video Encoding for Cloud and Edge Computing Instances
 
A Comprehensive Guide to DeFi Development Services in 2024
A Comprehensive Guide to DeFi Development Services in 2024A Comprehensive Guide to DeFi Development Services in 2024
A Comprehensive Guide to DeFi Development Services in 2024
 
Artificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopmentArtificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopment
 
Azure API Management to expose backend services securely
Azure API Management to expose backend services securelyAzure API Management to expose backend services securely
Azure API Management to expose backend services securely
 
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdfHow to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
 
Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024
 
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdfMonitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdf
 
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdfUnlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
 
GenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizationsGenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizations
 
June Patch Tuesday
June Patch TuesdayJune Patch Tuesday
June Patch Tuesday
 
dbms calicut university B. sc Cs 4th sem.pdf
dbms  calicut university B. sc Cs 4th sem.pdfdbms  calicut university B. sc Cs 4th sem.pdf
dbms calicut university B. sc Cs 4th sem.pdf
 
Presentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of GermanyPresentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of Germany
 
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
 
System Design Case Study: Building a Scalable E-Commerce Platform - Hiike
System Design Case Study: Building a Scalable E-Commerce Platform - HiikeSystem Design Case Study: Building a Scalable E-Commerce Platform - Hiike
System Design Case Study: Building a Scalable E-Commerce Platform - Hiike
 
Nordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptxNordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptx
 

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.