4 сентября 2020 года Международная организация по стандартизации (англ. «ISO») утвердила новую версию языка C++ под названием C++20. Мы уже ранее говорили о нововведениях в версии C++11, версии C++14 и версии C++17.
Нововведения, принятые в стандарте C++20, должны стать большим шагом в развитии языка С++, какими для своего времени стали нововведения стандарта C++11. Чтобы понять всю суть изменений C++20, позвольте мне кратко изложить эволюцию языка С++ в историческом контексте его стандартов.
Стандарты языка C++
Языку C++ уже без малого 40 лет. Что же произошло с ним за последние годы? Ниже приведен мой небольшой рассказ, в котором я постараюсь акцентировать ваше внимание на значимых нововведениях языка C++, начиная со стандарта C++98 и заканчивая сегодняшними днями.
C++98
В конце 1980-х годов Бьёрн Страуструп и Маргарет Эллис написали свою знаменитую книгу «Справочное руководство по языку программирования C++ с комментариями» (сокр. «ARM» от «Annotated C++ Reference Manual»). Выпуск данной книги преследовал две цели. Во-первых, к тому моменту уже существовало большое количество независимых реализаций C++ — вследствие этого книга ARM сыграла свою роль в описании возможностей языка C++. Во-вторых, ARM стала основой для первого стандарта языка C++: C++98 (ISO/IEC 14882). Стандарт C++98 содержал несколько особо важных инструментов, которыми мы пользуемся и по сей день: шаблоны, библиотека STL с её контейнерами и алгоритмами, строки и потоки ввода-вывода.
C++03
Начиная с версии C++03 (14882:2003), стандарт C++98 получил некоторые технические исправления, основную массу которых составляли описания нюансов реализации компиляторов для улучшения совместимости и переносимости программ между системами. Можно сказать, что сам язык практически не изменился, из-за чего некоторые авторы (даже сам Бьёрн Страуструп) оспаривают выделение данной версии в отдельный стандарт, вместо этого рассматривая C++03 как исправленную версию стандарта C++98. Изменения, вносимые стандартом C++03, настолько малозначительны, что ему не нашлось места на вышеприведенной временной шкале. На данный момент, стандарт C++03, который включает в себя C++98, сообщество программистов относит к устаревшему C++.
TR1
В 2005 году произошло нечто очень интересное. Был опубликован так называемый Технический Отчет 1 (сокр. «TR1» от англ. «Technical Report 1»). TR1 был большим шагом к C++11 и, следовательно, к современному C++. TR1 (TR 19768) основан на проекте boost, который, в свою очередь, был создан членами Комитета по стандартизации C++. TR1 содержит 13 библиотек, которые стали частью следующего стандарта C++, например: библиотека регулярных выражений, библиотека случайных чисел, умные указатели типа std::shared_ptr и хэш-таблицы.
C++11
C++11 ознаменовал собой новую эпоху языка C++, но мы просто называем его современным C++. Стандарт C++11 содержал большое количество нововведений, которые значительным образом повлияли на C++. Например, C++11 привнес компоненты из TR1, а также семантику перемещения, perfect forwarding (механизм прямых передач), вариативные шаблоны и спецификатор constexpr. Но это еще не всё! С появлением C++11 мы впервые получили стандартизованную модель памяти, которая легла в основу реализации многопоточной обработки информации.
C++14
C++14 — это небольшой стандарт языка C++, который привнес механизм блокировки чтения-записи, обобщенные лямбды и обобщенные constexpr-функции.
C++17
C++17 не является ни большим, ни маленьким стандартом. Он имеет две отличительные особенности: параллельные алгоритмы STL (Parallel STL) и стандартизированную файловую систему. Библиотека boost, представленная в C++11, также оказала большое влияние и на C++17. Мы получили от boost файловую систему и три новых типа данных: std::optional, std::variant и std::any.
C++20
Знакомьтесь, «большая четверка» стандарта C++20:
- ranges (диапазоны)
- coroutines (сопрограммы)
- concepts (концепции)
- modules (модули)
Раньше я бы написал «большая пятерка», но contracts (контракты) были вычеркнуты из общего списка на совещании по стандартизации в Кёльне.
Новая библиотека диапазонов (ranges) позволяет алгоритмам напрямую работать с контейнерами, комбинировать алгоритм с символом конвейера |
и применять их к бесконечным потокам данных.
Благодаря сопрограммам (сoroutines) асинхронное программирование может стать мейнстримом в C++. Сопрограммы являются основой для совместных задач, циклов событий, бесконечных потоков данных или конвейеров.
Введение концепций (concepts) связывают с дальнейшим развитием в языке С++ инструментария, основанного на парадигме обобщенного программированияого программирования. Они позволяют вам выразить свое намерение непосредственно через систему типов данных, обеспечивают соответствие используемых в шаблоне данных указанному набору критериев и проверяют это в начале процесса компиляции. Если что-то пойдет не так, вы получите короткое, но в то же время значимое сообщение об ошибке, вместо огромного списка сообщений об ошибках и предупреждений, ведущих куда-то вглубь шаблона.
Модули (modules) — это очень многообещающий механизм, являющийся новым способом разделения исходного кода, призванный преодолеть ограничения, возникающие из-за использования заголовочных файлов, и, в конечном счете, заменить всю систему препроцессоров. В результате мы должны получить более быстрый и простой способ сборки пакетов.
Но это далеко не всё, что есть в стандарте С++20. Вот несколько дополнительных нововведений:
- оператор трехстороннего сравнения
<=>
- календарь и расширения часовых поясов библиотеки chrono
- std::span как представление массива
- два новых ключевых слова: consteval и constinit
- designated initializers (назначенные инициализаторы)
- constexpr-контейнеры
- строковые литералы как параметры шаблона
- тип char8_t — стандартный тип для представления строк в формате UTF-8
Дополнительные ресурсы
Возможности С++20 — новые возможности С++ в версиях от С++11 до С++20 в формате таблиц на cppreference.
Modern C++ Features — статья от Anthony Calandra о новых возможностях стандарта С++20.