
На днях комитет ISO по стандартизации языка С++ (да, есть и такой) утвердил международный стандарт С++20. Возможности, которые представлены в спецификации, поддерживаются в компиляторах GCC, Clang и Microsoft Visual C++. Кроме того, стандартные библиотеки с поддержкой С++20 реализованы в рамках проекта Boost.
Следующий этап подготовка документа к публикации. Затем, в начале ноября, финальный вариант будет направлен в ISO, после чего он будет опубликован под формальным названием ISO/IEC 14882:2020. Сейчас комитет уже работает над следующим стандартом C++23 (C++2b). Под катом особенности С++20 с примерами кода.
Что нового?
Комитет добавил концепции, расширения шаблонов, которые позволяют определить набор требований к параметрам шаблона. Во время компиляции они ограничивают набор аргументов, которые могут приниматься в качестве параметров шаблона. Концепции дают возможность избежать логических несоответствий между свойствами типов данных, которые используются внутри шаблона, и свойствами типов данных входных параметров.
template<typename T> concept EqualityComparable = requires(T a, T b) { { a == b } -> std::boolean; { a != b } -> std::boolean; };
Приняты расширения для работы с модулями. Их можно использовать вместо заголовочных файлов. Модули предоставляют новый способ организации исходных текстов на основании определения границ компонентов, без подключаемых при помощи "#include" заголовочных файлов.
Добавлен макрос __VA_OPT__ для адаптивного раскрытия вариативных макросов в зависимости от наличия токенов в вариативном аргументе.
Добавлена поддержка оператора <=> для трехстороннего сравнения.
Поддерживаются инициализаторы элементов по умолчанию для битовых полей.
Появилась возможность лямбда-захвата выражений *this.
struct int_value { int n = 0; auto getter_fn() { // BAD: // return [=]() { return n; }; // GOOD: return [=, *this]() { return n; }; } };
Для классов теперь можно использовать параметры шаблона без типа.
struct foo { foo() = default; constexpr foo(int) {} }; template <foo f> auto get_foo() { return f; } get_foo(); // uses implicit constructor get_foo<foo{123}>();
Появилась возможность использования строковых литералов в параметрах шаблона. Поддерживается синтаксис инициализации в стиле Си. Те, что явно не перечисляются в списках инициализации поля, инициализируются по умолчанию.
struct A { int x; int y; int z = 123; }; A a {.x = 1, .z = 2}; // a.x == 1, a.y == 0, a.z == 2
Поддерживаются пустые члены структур данных.
Поддерживаются атрибуты likely и unlikely для информирования оптимизатора о вероятности срабатывания условной конструкции ("[[likely]] if (random > 0) {").
Появилась возможность использования диапазонов для инициализации значений переменной в цикле for
for (auto v = std::vector{1, 2, 3}; auto& e : v) {
Поддерживаются immediate функции, которые могут работать только с константами.
consteval int sqr(int n) { return n * n; } constexpr int r = sqr(100); // OK int x = 100; int r2 = sqr(x); // ERROR: 'x' не может использоваться как константа
В библиотеку добавлены:
- поддержка типа char8_t для строк UTF-8.
- заголовочные файлы bit (битовые операции) и version.
- возможность проверки префикса и суффикса строк (starts_with, ends_with).
- типажи std::remove_cvref, std::unwrap_reference, std::unwrap_decay_ref, std::is_nothrow_convertible и std::type_identity.
- функции std::midpoint, std::lerp, std::bind_front, std::source_location, std::visit, std::is_constant_evaluated и std::assume_aligned.
- поддержка массивов в std::make_shared.
- функция std::to_array для преобразования похожих на массив объектов в std::array.
Синтаксис перечислений теперь более удобен:
enum class rgba_color_channel { red, green, blue, alpha }; std::string_view to_string(rgba_color_channel my_channel) { switch (my_channel) { using enum rgba_color_channel; case red: return "red"; case green: return "green"; case blue: return "blue"; case alpha: return "alpha"; } }
В индексах запрещено использовать операции "," (a[b,c]). Большинство операций с переменными, объявленными с ключевым словом violate, включая запрещенные операции "++" и "--" со стандартными типами, не поддерживаются.
