LINUX.ORG.RU

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

 ,


2

7

Комитет ISO по стандартизации языка C++ утвердил финальный вариант спецификации, образующей международный стандарт «C++26». Представленные в спецификации возможности частично уже поддерживаются в компиляторах GCC (gnu.org), 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), позволяющей отслеживать и модифицировать элементы программы на стадии компиляции. Добавлены новые операторы «^^ (open-std.org)» для получения метаинформации о грамматической конструкции и «[:…:]» для выполнения обратного преобразования. Для преобразования и обработки полученной в ходе инспектирования информации предложена библиотека 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 (open-std.org) («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;

>>> Источник: OpenNET

👍👍👍👍👍

Проверено: Dimez ()
Последнее исправление: dataman (всего исправлений: 1)

Было бы хорошо расписать, как выкачать текст драфта. Потому что релиз они будут продавать за деньги, и получить его не удастся.

Saakx
()

90% из того, что приняли использоваться не будет

iLoveoOz
()
Ответ на: комментарий от chikanuc

линейная алгебра и simd

std::hive тоже пригодится.
Как и другие проекты его автора: https://plflib.org.

dataman 👍👍👍👍👍
() автор топика

Если ты делаешь компилятор ЯП настолько сложным, что отдельно взятый человек уже не способен разобраться в его коде за разумное время, то ты де-факто обладаешь полным контролем над всем что написанно на этом ЯП. :)

Stanson ☕☕☕☕☕
()
Ответ на: комментарий от Bfgeshka

Они сначала обкатывают решение в рамках boost, потом удачные варианты перетаскивают в std. Таким путем прошли, например, boost::filesystem (нынче std::filesystem) или shared_ptr&Co

AlexM
()
Последнее исправление: AlexM (всего исправлений: 1)
Ответ на: комментарий от kaldeon

А вот и дорогу к Spring проложили. Недавно как раз интересовались.

Там не та рефлексия. Оно по большей части про генерацию кода (с весьма ограниченными возможностями), т.е. плюсовый код обещает стать ещё более забористым.

borisych
()

Реализованы тривиальные бесконечные циклы без неопределенного поведения.

Дожили. Уже и тривиальный бесконечный цикл был UB! Потому что «it is desirable to express forward progress guarantees in a programming language because it unlocks a design space in concurrency and parallelism software and hardware design».

Хорошо конечно, что исправили, но как такое вообще могло попасть в стандарт?

Beewek 👍
()
Ответ на: комментарий от Beewek

но как такое вообще могло попасть в стандарт?

Хотели дурней эмбедщиков отучить от «while(1);» в пользу «while(1) sleep_power_level0();» но эмбедщики победили.

sarumeister
()
Ответ на: комментарий от dataman

Ну это ты прямо bleeding edge версии перечислил. А у меня там VS2022 была. И Clang вроде 19й был или около того.

Loki13 👍👍👍👍
()
Ответ на: комментарий от seiken

кто-нибудь из комитета C++ ушёл оттуда по причине тяжелых психиатрических проблем?

он туда пришел

olelookoe ☕☕☕
()
Ответ на: комментарий от VladimirP

Не распознал Б.Строуструпа на фото. Покажите, где он.

На нижнем фото, второй ряд, мужик в черной шляпе. Я вот тольно одно не понимаю, кто за эти годы изменился больше: он или C++.

Lucky
()

Клепают стандарты, я до сих пор 11 не освоил до конца

doomer
()
Ответ на: комментарий от AlexM

например, std::execution нет в бусте, единственная oss реализация есть в гитхабе nvidia. Но я вообще не понимаю зачем такое в стандарт тащить. Очень нишевая штука.

Reset 🤡🤡
()
Ответ на: комментарий от qulinxao3

Осн.знач - подобный заборам

Сильнодействующий; едкий, крепкий

Забористый сибирский мороз проникал в места стыков панелей, даже внутри помещений выступала изморось. – Юрий Юша, «Крупноблочный десант»

Loki13 👍👍👍👍
()

Язык C++ становится все загадочней и непознаваемей.

static_assert(r == r && r == s);

Чтобы понимать кому и зачем понадобилось сравнивать переменную саму с собой, надо знать историю развития языка, исторически обусловленные трюки по возможности подавления предупреждений компилятора, учесть возможность появления типов у которых нет оператора сравнения (кому-то же такие типы понадобились), а потом узнать о инструментах проверки неполных типов (ведь мы сами себе сделали типы без оператора сравнения). Далее надо добраться до выражений, которые всегда истинны, но вычисляются. А затем полирнуть инстанцированием шаблонов и SFINAE триггерами.

Ящитаю это успех.

Xintrea 👍👍👍
()
Ответ на: комментарий от Skullnet

MOC-компилятор - это не про фичи С++, а про фичи макроопределений. Собственно, moc-компилятор всего лишь раскрывает макрос Q_OBJECT. Фич достаточно, но различные компиляторы имеют ньюансы раскрытия макросов, из-за чего написание макросов, подобных Q_OBJECT, становится либо слишком громоздким, либо невозможным. По крайней мере, примерно такие слова говорились, когда это всё появилось. Сейчас живых компиляторов меньше, но всё равно, попыток перейти на макросы языка не предпринимается. Н.Я.П., различия между MSVC и gcc всё ещё существенны.

lenin386 👍👍👍👍👍
()
Последнее исправление: lenin386 (всего исправлений: 1)
  • Переведено в разряд устаревших выполнение неявных преобразований перечисляемых значений в арифметических вычислениях.

А про Си-шные библиотеки все забыли?

AlexVR 👍
()
Ответ на: комментарий от Xintrea

Чтобы понимать кому и зачем понадобилось сравнивать переменную саму с собой,

constexpr double z = std::numeric_limits<double>::quiet_NaN();
AlexVR 👍
()
Ответ на: комментарий от lenin386

MOC-компилятор - это не про фичи С++, а про фичи макроопределений

Вот потому, что вы говорите то, что не думаете и думаете то, что не думаете, вот в клетках и сидите. И вообще, весь этот горький катаклизм, который я тут наблюдаю… и Владимир Николаевич тоже… (c)

Комитет до сих пор в простые истины не врубается кмк: макросы нужно раскрывать и результат раскрытия куда-то складывать, ровно точно также нужно поступать и с шаблонами. Здесь, видимо, какая-то крыса пытается на компилятор сгрузить работу, которая компилятору нафиг не упала, а в итоге страдают все подряд, однако, есть оправдание: мы - ылита и на такие мелочи как откровенная всратость языка, отсутствие системы сборки и пр. мы внимания не обращаем.

borisych
()
Ответ на: комментарий от Lucky

Да где же??? В шляпе я там только какого-то негра вижу.

VladimirP
()
Ответ на: комментарий от Xintrea

И что на этом copperspice успели написать? Более десятка лет то прошло.

Это тот же Qt, только библиотеки заменяешь при сборке и вроде ряд макросов заменяется.

Вот демо: https://github.com/copperspice/kitchensink

Dr64h 👍
()

А ещё не сделали класса для строк с фиксированным размером? Как std::array, но с (почти) всей функциональностью std::string.

Типа один раз задал размер, например 50 символов и дальше всё происходит в рамках это размера. Меньше можно, но больше - нельзя. Соответственно память выделяется только один раз.

sena 👍
()
Последнее исправление: sena (всего исправлений: 2)
Ответ на: комментарий от seiken

какой-то декомпилятор

Зачем какой-то декомпилятор, если вся метаинформация о классе хранится в скомпилированном .class и загружается класслоадером? И доступ осуществляется стандартным api.

WatchCat 👍
()
Ответ на: комментарий от sena

А ещё не сделали класса для строк с фиксированным размером? Как std::array, но с (почти) всей функциональностью std::string.

В https://github.com/teslamotors/fixed-containers есть FixedString.

dataman 👍👍👍👍👍
() автор топика
Ответ на: комментарий от Stanson

Фронтенд компилятора это самая простая его часть - в нем можно разобраться за разумное время, а бэкэнд от языка не зависит. И сложный он не потому что C++ сложный а по другим причинам

Reset 🤡🤡
()
Ответ на: комментарий от eao197

Да, похоже на то что надо, тут ниже ещё @dataman ссылку на ещё одну альтернативу прислал. Но хотелось бы в стандарте.

sena 👍
()

Сколько тетенек однако. Интересно, они это тоже члены комитета, или подружек с собой нахаляву приволокли?

Lusine 🤡
()

STL выкидывать нахрен надо уже, а они продолжают его раздувать...

mittorn ☕☕☕☕☕
()
Ответ на: комментарий от unDEFER

Большинство этих фич в Ди уже 100 лет прекрасно работают.

Полтора программиста на Ди во всем мире могут в очередной раз порадоваться.

eao197 👍👍
()

А вот есть среди здесь люди, которые прямо все плюсы, все стандарты, успевают охватывать? Вот вышел новый стандарт, а к этому времени ты успел весь предыдущий освоить, проработать, понять. И так каждый раз

pihter 👍👍👍
()

смотришь но эти нововведения и начинаешь любить все остальное что только кроме... язык превращается в непонятное нечитаемое нечто.

это действительно нужно или ... (у кого свои идеи/мысли)?

sunjob 👍
()
Ответ на: комментарий от CrX

да в чем «суть то»? раньше (когда изучал его) - все было пристойно, со вкусом, чуством, расстановкой :о) а сейчас - это уже совсем не тот торт, что был! все больше на какую-то клюкву походит? (старый код можно просто беглым взглядом сканировать, а этот уже ... простите-увольте, я столько не авыкурю)

sunjob 👍
()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.