Мы поговорим о восьми удобных изменениях, которые влияют на ваш повседневный код. Четыре изменения касаются самого языка, а ещё четыре — его стандартной библиотеки. Некоторые примеры я брал из докладов на конференциях Russian C++ User Group — за это огромное спасибо её организаторам и докладчикам! Я брал примеры из: Удобно декомпозировать std::pair, std::tuple и структуры с помощью нового синтаксиса: В C++17 есть ограничения декомпозиции при объявлении: Декомпозиция при объявлении в принципе может раскладывать любой класс — достаточно один раз написать подсказку путём специализации tuple_element, tuple_size и get. Подробнее читайте в статье Adding C++17 structured bindings support to your classes (blog.tartanllama.xyz) Декомпозиция при объявлении хорошо работает в контейнерах std::map<> и std::unordered_map<> со старым методом .insert() и двумя новыми методами : Пример декомпозиции с try_emplace и декомпозиции key-value при обходе map: Ключевые правила: Вы можете создавать свои подсказки для автоматического вывода параметров шаблона: см. Automatic_deduction_guides Интересная особенность: конструктор из initializer_list<> пропускается для списка из одного элемента. Для некоторых JSON библиотек (таких как json_spirit) это может оказаться фатальным. Не играйтесь с рекурсивными типами и контейнерами STL! Избегайте вложенности пространств имён, а если не избежать, то объявляйте их так: Ключевые правила: В C++ приходится добавлять break после каждого case в конструкции switch, и об этом легко забыть даже опытному разработчику. На помощь приходит атрибут fallthrough, который можно приклеить к пустой инструкции. Фактически атрибут приклеивается к case, следующему за пустой инструкцией. Чтобы воспользоваться преимуществами атрибута, в GCC и Clang следует включит предупреждение -Wimplicit-fallthrough. После включения этой опции каждый case, не имеющий атрибута fallthrough, будет порождать предупреждение. В проектах с высокими требованиями к производительности могут практиковать отказ от выброса исключений (по крайней мере в некоторых компонентах). В таких случаях об ошибке выполнения операции сообщает код возврата, возвращённый из функции. Однако, очень легко забыть проверить этот код. Если вы используете, например, свой класс ошибок, то вы можете указать атрибут единожды в его объявлении. Иногда программисты создают переменную, используемую только в отладочной версии для хранения кода ошибки вызванной функции. Возможно, это просто ошибка дизайна кода, и возвращаемое значение следовало обрабатывать всегда. Тем не менее: Правила: Класс string_view хорош тем, что он легко конструируется и из std::string и из const char* без дополнительного выделения памяти. А ещё он имеет поддержку constexpr и повторяет интерфейс std::string. Но есть минус: для string_view не гарантируется наличие нулевого символа на конце. Применение optional<> и variant<> настолько широко, что я даже не буду пытаться полностью описать их в этой статье. Ключевые правила: Пример кода с optional: Пример кода с variant: здесь мы используем variant для хранения одного из нескольких состояний в случае, когда разные состояния могут иметь разные данные Преимущество variant в его подходе к управлению памяти: данные хранятся в полях значения типа variant без дополнительных выделений памяти. Это делает размер типа variant зависимым от типов, входящих в его состав. Так может выглядеть таблица размеров на 32-битных процессорах (но это неточно):  Может быть, для манипуляций с байтами лучше опираться на библиотеку GSL (C++ Core Guidelines Support Library). Ключевые правила: Чем плох boost::filesystem? Оказывается, у него есть несколько проблем дизайна: Любой опытный программист знает о разнице в обработке путей между Windows и UNIX-системами: Конечно же filesystem абстрагируется от подобных различий и позволяет легко работать как с платформо-зависимыми строками, так и с универсальным UTF-8: Функция std::clamp дополняет функции min и max. Она обрезает значение и сверху, и снизу. Аналогичная функция boost::clamp доступна в более ранних версиях C++. Правило "не переизобретайте clamp" можно обобщить: в любом крупном проекте избегайте дублирования маленьких функции и выражений для округлений, обрезаний значений и т.п. — просто один раз добавьте это в свою библиотеку. Аналогичное правило работает для задач обработки строк. У вас есть своя маленькая библиотека для строк и парсинга? В ней есть парсинг или форматирование чисел? Если есть, замените свою реализацию на вызовы to_chars и from_chars Функции to_chars и from_chars поддерживают обработку ошибок. Они возвращают по два значения: Поскольку в прикладном коде способ реакции на ошибку может различаться, следует помещать вызовы to_chars и from_chars внутрь своих библиотек и утилитных классов.