Утверждён стандарт C++26

Комитет ISO по стандартизации языка C++ завершил утвердил финальным вариант спецификации, образующей международный стандарт «C++26». Представленные в спецификации возможности частично уже поддерживаются в компиляторах GCC, Clang и Microsoft Visual C++. Поддерживающие C++26 стандартные библиотеки реализованы в рамках проекта Boost.

В следующие два месяца утверждённая спецификация будет находиться на стадии подготовки документа к публикации, на которой будет проведена работа по редакторской правке орфографических ошибок и опечаток. В начале ноября результирующий вариант документа будет направлен в ISO для публикации под формальным именем ISO/IEC 14882:2026.

Основные особенности C++26:

  • Реализованы элементы контрактного программирования (Contracts), позволяющие определять формальные спецификации интерфейсов при помощи трёх новых операторов: pre (предусловие), post (постусловие) и contract_assert (проверка утверждения). Оператор «pre» определяет предварительные условия, которые должны быть выполнены перед вызовом (проверка входных данных); «post» — условия, которые должны соблюдаться после выполнения (требования к выходным данным); contract_assert — условия возникновения исключений. Возможность появится в GCC 16. int f(const int x) pre (x != 1) // требования ко входным данным post (r : r == x && r != 2) // требования к результату; r — значение с результатом { contract_assert (x != 3); return x; }
  • Добавлена поддержка рефлексии (Reflection), позволяющей отслеживать и модифицировать элементы программы на стадии компиляции. Добавлены новые операторы «^^» для получения метаинформации о грамматической конструкции и «[:…:]» для выполнения обратного преобразования. Для преобразования и обработки полученной в ходе инспектирования информации предложена библиотека std::meta и доступны такие возможности, как вычисления с константами. Поддержка рефлексии будет добавлена в GCC 16. constexpr int i = 42, j = 42; constexpr std::meta::info r = ^^i, s = ^^i; static_assert(r == r && r == s); static_assert(^^i != ^^j); // ‘i’ и ‘j’ имеют различные значения. static_assert(constant_of(^^i) == constant_of(^^j)); // ‘i’ и ‘j’ одинаковы static_assert(^^i != std::meta::reflect_constant(42)); // отличается от значения 42
  • Добавлен оператор «template for» для перебора элементов, таких как пакеты параметров, похожие на кортежи объекты и результаты рефлексии (метаобъекты), на этапе компиляции в стиле обычного цикла. При выполнении «template for» тело цикла раскрывается для каждого элемента и каждая итерация обрабатывается в отдельной области видимости, в которой меняющаяся в цикле переменная является константой. В контексте рефлексии «template for» может применяться для обхода свойств классов или перечислений. Возможность появится в GCC 16. void f() { template for (constexpr int I : std::array{1, 2, 3}) { static_assert(I < 4); } } будет раскрыто в: void f() { { constexpr auto&& __range = std::array{1, 2, 3}; constexpr auto __begin = __range.begin(); constexpr auto __expansion-size = __range.end() — __begin; // 3 { constexpr int I = *(__begin + 0); static_assert(I < 4); } { constexpr int I = *(__begin + 1); static_assert(I < 4); } { constexpr int I = *(__begin + 2); static_assert(I < 4); } } }
  • Добавлен фреймворк std::execution для асинхронного и параллельного выполнения кода. Предоставляются объекты scheduler, определяющий планировщик выполнения работ (поток, пул потоков, GPU, event loop), sender, определяющий выполняемую работу, и receiver — обработчик результата. using namespace std::execution; scheduler auto sch = thread_pool.scheduler(); sender auto begin = schedule(sch); sender auto hi = then(begin, []{ std::cout < «Hello world! Have an int.»; return 13; }); sender auto add_42 = then(hi, [](int arg) { return arg + 42; }); auto [i] = this_thread::sync_wait(add_42).value();
  • Добавлена библиотека std::simd для распараллеливания выполнения операций над данными при помощи наборов инструкций SIMD, таких как AVX-512 и NEON, с использованием стандартной системы типов C++. std::simd<float> a = {1.0f, 2.0f, 3.0f, 4.0f}; std::simd<float> b = {5.0f, 6.0f, 7.0f, 8.0f}; std::simd result = a + b;
  • Предложена реализация вектора (массива) переменного размера std::inplace_vector, размещаемого в стеке, размер которого определяется на этапе компиляции. API близок к std::vector, но элементы массива хранятся не в «куче», а внутри объекта. inplace_vector a(10); inplace_vector b(std::move(a)); assert(a.size() == 10);
  • Добавлена директива «#embed», предназначенная для встраивания в код бинарных ресурсов. const unsigned char icon_display_data[] = { #embed «art.png» };
  • Добавлена поддержка генерации и обработки исключений на этапе компиляции при ошибках в контексте constexpr. constexpr std::optional<unsigned> checked_divide(unsigned n, unsigned d) { try { return divide(n, d); } catch (…) { return std::nullopt; } } constexpr date parse_date(std::string_view input) { auto [correct, year, month, day] = ctre::match<«([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})»>(input); if (!correct) { throw incorrect_date{input}; } return build_date(year, month, day); }
  • Реализована структура данных std::hive для неупорядоченного хранения данных и обеспечения повторного использования памяти, освободившейся после удалённых элементов. Структура оптимизирована для нагрузок с высокой интенсивностью добавления и удаления элементов в произвольном порядке. В отличие от массивов, удаление элемента в std::hive не вызывает сдвига других элементов, а приводит к пометке удалённого элемента пустым с последующим заполнением освободившейся позиции при добавлении нового элемента.
  • Добавлена библиотека std::linalg c API для линейной алгебры, основанный на BLAS.
  • Добавлена поддержка механизма синхронизации Hazard pointer, позволяющего без выставления блокировок предотвратить освобождение памяти объектов, с которыми продолжается работа в других потоках. При удалении объекта, он лишь помечается удалённым, но занимаемая объектом память освобождается только когда все потоки снимут hazard-указатель, выставляемый во время работы с объектом.
  • Добавлена поддержка механизма синхронизации RCU (Read-Copy Update) — при операциях записи создаётся новый экземпляр объекта, а операции чтения не блокируются, а продолжают работать со старым экземпляром. После завершения изменения новый экземпляр становится активным и новые операции чтения уже производятся с ним, а старый экземпляр удаляется после завершения читающих его потоков.
  • Внесены изменения для усиления безопасности стандартной библиотеки, такие как проверки допустимых значений и выхода за границы буфера. Например, при доступе к элементу «constexpr reference operator[](size_type idx) const;» добавляется проверка условия «idx < size()".
  • Предоставлена возможность использования ключевого слова «constexpr» с разновидностью оператора «new» (placement new) для размещения объекта в заранее выделенной памяти во время компиляции.
  • Добавлена поддержка структурированных привязок (structured binding) в контексте «constexpr», т.е. ссылки на константные выражения теперь сами могут быть константными выражениями. Поддержка реализована для массивов и простых структур. constexpr int arr[] = {1, 2}; constexpr auto [x, y] = arr;
  • В структурированные привязки добавлена возможность использования синтаксиса «…» для указания пакетов (pack), захватывающих оставшееся число элементов из присваиваемой последовательности. auto [x,y,z] = f(); // в переменные x, y, z будут записаны три элемента, возвращённые f(). auto […xs] = f(); // в пакет xs будут записаны все элементы, возвращённые f(). auto [x, …rest] = f(); // В x будет записан первый элемент, а в rest — остальные. auto [x, y, …rest] = f(); // В x будет записан первый элемент, в y — второй, а в rest — третий. auto [x, …rest, z] = f(); // в x — первый, в rest — второй, в z — третий.
  • Добавлена поддержка «тривиальной перемещаемости» типов (Trivial Relocatability), позволяющей оптимизировать перемещения объектов заданного типа через их клонирование в памяти без вызова конструкторов или деструкторов. Для классов реализованы свойства memberwise_trivially_relocatable и memberwise_replaceable, а для низкоуровневого перемещения одного или нескольких объектов добавлены функции trivially_relocate_at и trivially_relocate.
  • Реализована поддержка прикрепления функции main() к глобальному модулю и определения функции main() в именованных модулях.
  • Добавлен вариативный оператор «friend» («friend Ts…»).
  • Реализованы атрибуты для структурированных привязок;
  • Добавлен синтаксис ‘= delete(«причина»)’.
  • В базовый набор символов включены «@», «$» и «`».
  • Предоставлена возможность применения структурированного связывания (structured binding) в качестве условия в операторах if и switch.
  • Добавлена возможность использования сразу нескольких переменных-заполнителей с именем «_» в одной области видимости, например, теперь являются корректными конструкции: struct S { int _, _; }; void func() { int _, _; } void other() { int _; // ранее выводилось предупреждение в режиме -Wunused }
  • Предоставлена возможность использования строковых литералов в контексте, в котором они не используются для инициализации массива символов и не попадают в результирующий код, а применяются только во время компиляции для диагностических сообщений и препроцессинга, например, в качестве параметров директив и атрибутов _Pragma, asm, extern, static_assert, [[deprecated]] и [[nodiscard]].
  • Добавлены встроенные функции: «__builtin_is_within_lifetime» для проверки активности альтернативы в объединениях (union) и «__builtin_is_virtual_base_of» для проверки является ли базовый класс виртуальным.
  • Реализованы тривиальные бесконечные циклы без неопределенного поведения.
  • Обеспечен вывод ошибки при удалении указателя на неполный тип.
  • Объявлен устаревшим синтаксис определения вариативных параметров с многоточием без предшествующей запятой (например, когда указывается «void e(int…)» вместо «void e(int, …)»).
  • Запрещено использование макросов для объявления модулей.
  • Переведено в разряд устаревших выполнение неявных преобразований перечисляемых значений в арифметических вычислениях. int main() { enum E1 { e }; enum E2 { f }; bool b = e <= 3.7; // устарело int k = f — e; // устарело int x = +f — e; // OK }
  • Прекращена поддержка прямого сравнения массивов. int arr1[5]; int arr2[5]; bool same = arr1 == arr2;
  • Объявлен устаревшим шаблонный класс is_trivial.

    Աղբյուր: opennet.ru
Գնել վստահ հոստինգ կայքերի համար՝ DDoS պաշտպանությամբ, VPS VDS սերվերներ 🔥 Գնել վստահ հոստինգ կայքերի համար՝ DDoS պաշտպանությամբ, VPS VDS սերվերներ | ProHoster