C++: Эволюция стандартов от 11 до 23
Перед собеседованиями часто задаюсь вопросом: что самое главное в каждом стандарте? Чтобы упростить себе подготовку, решил написать краткий обзор ключевых изменений в стандартах C++.
Данный пост навеян выступлениями Тимура Домлера.
C++23
Основывался на выступлении Тимура Домлера на CppCon 2022.
- deducing this
 Добавляет возможность передавать ссылку на вызывающий объект (аналогselfв Python).
 Заменяет CRTP (Curiously Recurring Template Pattern), позволяя писать базовые классы с реализацией методов, зависящих от полей или методов наследника, без шаблонов.
 Удобная перегрузка методов по типу объекта:const,&,&&.
 В лямбды можно прокидывать самих себя для рекурсии.
- std::expected
 Унифицированный способ возвращения результата и ошибки одновременно. Содержит информацию об ошибке, если она есть (аналогResultв Rust).
- std::mdspan
 Обёртка для работы с многомерными массивами. Создаём область памяти, размечаем её как многомерный массив и работаем с удобными индексами.
- std::print
 Инструмент для форматирования и вывода строк. Ранее был доступен толькоstd::format.
C++20
Основывался на выступлении Тимура Домлера на CppCon 2020.
- Coroutines
 Расширяют модель функций, позволяя приостанавливать и возобновлять выполнение. Отлично упрощают код с множеством обратных вызовов.
 На момент выхода стандарта они ещё сырые, рекомендуется использовать с готовыми библиотеками.
- Concepts
 Позволяют задавать ограничения на типы в шаблонах. Ранее это делалось через SFINAE иstd::enable_if, но выглядело сложно:template<typename T, std::enable_if_t<std::is_integral_v<T>, void*> = nullptr>Теперь это проще и читаемее: template <std::integral T> bool func(T arg) {} // or bool func(std::integral auto arg) {}
- Ranges
 Уменьшают потребность в циклах. Позволяют комбинировать стандартные алгоритмы в ленивой манере черезviewsи оператор|.
 Вместо передачи итераторов алгоритмам можно сразу работать с контейнерами.
- Modules
 Замена заголовочным файлам. Работают аналогично модулям в Python.
C++17
Ключевые изменения (по личному мнению):
- std::string_view
 Избавляет от копирования строк. Храним только ссылку и длину.
- Structured Bindings
 Декомпозиция составных объектов: пар, кортежей, массивов. Работает как в Python.
- std::optional, std::variant, std::any
 Удобные типы для хранения различных значений.
- Fold Expressions
 Упрощают работу с параметрами шаблонов, избавляя от необходимости рекурсии.
- if constexpr
 Делает шаблоны читаемее, удаляя ненужные ветки на этапе компиляции. В отличие от макросов, проверяет корректность кода.
- if с инициализацией
 Позволяет объявлять переменные прямо в условии (как вfor).
- Parallel Algorithms in std
 Многопоточные версии стандартных алгоритмов.
- std::filesystem
 Набор инструментов для работы с файловой системой (портирован из Boost).
C++14
Этот стандарт не богат на революционные изменения:
- std::make_unique
 Удобное создание умных указателей.
- Placeholder type specifiers
 Выведение типа возвращаемого значения (черезauto). Полезно в шаблонах.
C++11
Этот стандарт стал основой современного C++. Без него язык уже невозможно представить.
- Move Semantics и rvalue-ссылки
 Оптимизация работы с временными объектами.
- auto
 Автоматическое выведение типов.
- lambda expressions
 Просто лямды, функции внутри функций.
- Brace-or-equal initializers
 Списки инициализации. Использование{}вместо()для инициализации.
- Smart pointers
 Умные указатели:std::shared_ptr,std::unique_ptr.
- constexpr
 Вычисление значений на этапе компиляции.
- Variadic templates + std::tuple
 Шаблоны с переменным числом аргументов. На их основе созданstd::tupleдля хранения значений разных типов.