Привет! На связи Антон Полухин из Техплатформы Городских сервисов Яндекса. Сегодня я расскажу о ноябрьской встрече Международного комитета по стандартизации языка программирования C++, в которой принимал активное участие. Это была первая из встреч, связанных с «полировкой» C++26. Другими словами, новые фичи C++ пока не появятся — комитет должен только проработать замечания всех стран-участников, включая наши замечания от России.

Однако от плана немного отступили и втащили некоторые новинки как ответы на пожелания участников комитета:

  • std::integer_sequence оброс новой функциональностью,

  • std::format научился в constexpr.

Помимо этого, поправили множество багов, перековыряли связку Hardening + Contracts, внесли улучшения во многие части стандартной библиотеки.


std::integer_sequence

В P1789 std::integer_sequence обзавёлся методами, позволяющими использовать его в structured binding и template for:

constexpr auto [...index] = std::make_index_sequence<COUNT>();
// Теперь с `index` можно работать как с обычным pack
auto sum = (index + ...);  // 0 + 1 + 2 + 3 + 4 +...

// Или даже вот так:
template for(constexpr size_t index : std::make_index_sequence<COUNT>()) {
    foo<index>(std::get<index>(some_tuple));
}

Новинка будет особенно полезна для рефлексии. Она позволит писать код компактнее, без лямбд для раскрытия std::integer_sequence:

constexpr auto members = nonstatic_data_members_of(
    ^^Aggregate,
    std::meta::access_context​::​​unchecked()
);

constexpr auto [...indexes] = std::make_index_sequence<members.size() / 2>();
serialize_first_half(aggregate.*[:members[indexes]:]...);

std::format

Большая радость (!) для всех пользователей: std::format научился работать в constexpr. Разве что с одним ограничением: нельзя форматировать с помощью локалей или чисел с плавающей точкой. Но даже с таким ограничением открывается большое окно возможностей: например, можно реализовать более продвинутые сообщения об ошибках в ваших библиотеках. Так, в ? userver FastPimpl вместо...

    // Use a template to make actual sizes visible in the compiler error message.
    template <std::size_t ActualSize /* ... */>
    static void Validate() noexcept {
        static_assert(
            Size >= ActualSize,
            "invalid Size: Size >= sizeof(T) failed"
        );
        // ...
    }

...можно будет по-человечески написать:

    // Use a template to make actual sizes visible in the compiler error message.
    template <std::size_t ActualSize /* ... */>
    static void Validate() noexcept {
        static_assert(
            Size >= ActualSize,
            std::format("Size should be set to at least {}.", ActualSize).c_str()
        );
        // ...
    }

Больше деталей в P3391.

Контракты и Hardening

Контракты C++ — одна из самых ожидаемых и при этом самых холиварных фич C++26. Поэтому подгруппа Evolution целых два дня работала над различными замечаниями от стран по контрактам.

Практически все замечания были отклонены на голосованиях. Одно из ярких исключений — hardening стандартной библиотеки через контракты.
История тут приключилась, на мой взгляд, занятная: некоторые страны хотели отвязать hardening стандартной библиотеки от механизма контрактов, некоторые (например, мы) хотели сохранить возможность кастомизировать поведение при срабатывании ассерт’а в стандартной библиотеке. А вот сами разработчики стандартных библиотек C++ заметили, что hardening с контрактами... не работает.

Засада крылась в формулировках:

  • Hardening — это про терминирование приложения в случае нарушения контракта стандартной библиотеки.

  • Контракты — это про возможность обнаруживать нарушения контракта и реагировать на них.

В итоге в стандарт закралось то, чего никто не хотел. А именно: «Стандартная библиотека считается hardened, даже если нарушение контракта просто логируется». При этом неопределённое поведение при использовании стандартной библиотеки оставалось: приложение продолжало работать, но при этом делать неожиданные вещи.

Как итог, на встрече единогласно приняли P3878: «Стандартная библиотека считается hardened, если приложение терминируется при нарушении контракта». Таким образом, мы закрыли сразу пять замечаний от стран-участников.

Trivial relocation

Trivial relocation в С++26 не будет. Было решено его удалить, так как практически все разработчики компиляторов сообщили, что есть платформы и ситуации, в которых текущее поведение trivial relocation невозможно реализовать.

Trivial relocation будет дорабатываться уже для C++29, а не в C++26 P3920.

Рефлексия и friend injection

Один из вопросов от участников из России был таким: «Если теперь рефлексия С++26 позволяет делать statefull metaprogramming, то не надо ли закрыть Core issue 2118, который пытается запретить statefull metaprogramming через friend injection?»

Вопрос важен в частности для пользователей библиотеки Boost.PFR, которая как раз может использовать хитрость из бага CWG2118 для рефлексии агрегатов в C++14.

Ответ Core: «Техника, описанная в CWG2118, позволяет намного больше, чем C++26 reflection. В частности, C++26 reflection injection не может вырваться за пределы класса или функции. При этом CWG2118 слишком строг в текущей формулировке, но закрывать как Not a Defect мы его не готовы».

Хорошо, что Boost.PFR работает и без использования хаков из CWG2118.

Прочие фиксы

  • optional<T&> теперь обязан быть trivially copyable P3836;

  • добавлены std::move и noexcept для различных flat_* контейнеров P3567;

  • std::execution::when_all теперь отправляет стоп-сигналы, только если один из «детей» их отправляет P388;

  • atomic_ref<T> научился конвертироваться в atomic_ref<const T> P3860.

И ещё почти сотня менее заметных багфиксов, доработок и улучшений.

Вместо итогов

Работа комитета не останавливается, подгруппы разбирают баги в онлайне. Сделать предстоит много: всего к C++26 было отправлено более 400 замечаний.

Остаётся нерешённым множество важных для нас комментариев, которые влияют на производительность и надёжность программ на C++. В частности, на этом заседании не дошли руки до P3725, который делает надёжный и безопасный std::ranges::filter, не подверженный проездам по памяти и Segmentation Fault в примерах наподобие:

std::vector<std::string> coll1{"Amsterdam", "Berlin", "Cologne", "LA"};
  // Перемещаем длинные строки в обратном порядке в другой контейнер
  auto large = [](const auto& s) { return s.size() > 5; };
  auto sub = coll1 | std::views::filter(large)
                   | std::views::reverse
                   | std::views::as_rvalue
                   | std::ranges::to<std::vector>();

А в скором времени пройдут конференции по C++, где можно будет поймать представителей РГ21, задать им вопросы, узнать что-то новое и интересное.

Буду рад встрече!

P.S.: некоторые ссылки на P???? документы могут ещё не работать, т.к. они не опубликованы. Со временем ссылки заработают

Комментарии (107)


  1. eao197
    26.11.2025 07:21

    Антон, а поднимается ли в комитете вопрос изменения периодичности выхода стандартов С++?
    Например, выпускать их не раз в три года, а раз в два года, раз в год или даже два раза в год?

    Сейчас получается следующая ситуация: есть некий жесткий дедлайн, ибо если что-то не входит в C++26, то затем придется ждать целых три года. Как раз пример с trivial relocation. В C++26 не попадает, но, возможно, уже в следующем году это предложение будет доработано, ему придется ждать до C++29.

    А вот если бы стандарт выходил раз в год, то окончательный trivial relocation мог бы войти в C++27.

    Как я понимаю, комитет сейчас работает по "train model" (если не ошибся с названием): в работе постоянно находится N предложений. К некоторой отсечке времени (за полгода-год до финализации) в новый стандарт включаются те предложения, прогресс по котором признан достаточным. А остальные предложения продолжаются разрабатываться.

    В этой модели, в теории, без разницы как часто делается отсечка по времени -- раз в три года или раз в два года. Или даже два раза в год.


    1. antoshkka Автор
      26.11.2025 07:21

      Выпуск стандарта ещё влечёт за собой накладные расходы - формальное создание особого черновика, сбор коментариев от стран, испраление замечаний, финализация стандарта в вышестоящих инстанциях ISO... Это достаточто ресурсоёмкие процессы

      Пока кажется что 3 года - отличный баланс между скоростью выпуска новых фичей и уменьшением мороки для людей в комитете


      1. eao197
        26.11.2025 07:21

        формальное создание особого черновика, сбор коментариев от стран, испраление замечаний

        А разве нет возможности это распараллелить? Т.е. вот произошла отсечка времени, например, летом 2025-го. Некая группа далее занимается обслуживанием бюрократии для оформления текста стандарта. А остальные возобновляют работы над текущими предложениями.

        финализация стандарта в вышестоящих инстанциях ISO... Это достаточто ресурсоёмкие процессы

        А тут неизбежно возникает следующий вопрос: а так ли важна сейчас для C++ именно ISO стандартизация?

        Ну т.е. роль ISO стандарта в начале 1990х была понятна.

        Но сейчас-то зачем?

        Допустим, будет условная некоммерческая организация C++ Foundation, которая раз в N месяцев выпускает некий свой документ под названием C++YY language specification. И все.

        По факту же, всем компиляторостроителям абсолютно похер на содержимое стандарта: есть в стандарте фичи X1, X2, X3, X4 и X5, а мы сделаем поддержку только X1, X3 и X5. Остальные когда-нибудь, когда руки дойдут. Если дойдут.

        И смысл наличия ISO-шного стандарта для непосвященных совершенно ускользает в современных реалиях.


        1. antoshkka Автор
          26.11.2025 07:21

          А разве нет возможности это распараллелить?

          Оно уже распараллелено, насколько это возможно. Однако, есть критические секции, которые не паралеллятся или плохо паралеллятся

          а так ли важна сейчас для C++ именно ISO стандартизация?

          Как ни странно - да. C++ чуть ли не единственный современный язык программирования, который можно использовать в приложениях, напрямую влияющих на жизнь человека (самолёты, автомобили, медицинское оборудование, ...). А для такого использования нужна ISO стандартизация.

          Без этого - потеряется ощутимая часть пользователей


          1. eao197
            26.11.2025 07:21

            C++ чуть ли не единственный современный язык программирования, который можно использовать в приложениях, напрямую влияющих на жизнь человека (самолёты, автомобили, медицинское оборудование, ...)

            Мне казалось, что у Ada там позиции гораздо крепче, чем у C++.

            Ну и такими темпами скоро С++у только и останется, что цепляться за ниши, в которых есть формальное требование наличия ISO-стандарта.

            Да и то до тех пор, пока каким-нибудь решением американского конгресса директивно запретят использовать Си и C++ под предлогом небезопасности. И начнут вместо применять условый Rust без оглядки на отсутствие ISO-стандарта для оного.


            1. rsashka
              26.11.2025 07:21

              Мне казалось, что у Ada там позиции гораздо крепче, чем у C++.

              Вы правы в том, что С++ есть чему получиться у Ada. Это касается требований к языку в части безопасной разработки перед началом его создания, которые отсутствовали у С и С++.


    1. Jijiki
      26.11.2025 07:21

      и потом разраб такой, по каким-либо причинам забивает на язык, и возвращается в язык спустя 3 года, и такой сидит и перед ним пролетают килотонны правил, ""так это можно, это нельзя, это было в легаси, так стоп это же теперь в самом новом стандарте" )


      1. eao197
        26.11.2025 07:21

        Типа сейчас очень просто взять и после C++14 переучиться на C++26. Ага.

        Так-то наоборот, если принимать стандарт раз в год, то дельта изменений по сравнению с предыдущим будет меньше.


        1. rsashka
          26.11.2025 07:21

          Типа сейчас очень просто взять и после C++14 переучиться на C++26

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


          1. eao197
            26.11.2025 07:21

            Так вообще не нужно переучиваться, так как процесс стандартизации обеспечивает обратную совместимость и не требуется ничего переписывать,

            Во-первых, вы смело можете адресовать свои слова оратору выше. Это он чего-то опасается.

            Во-вторых, как бы опыт С++11 говорит, что не так все однозначно.

            А принятие модулей в стандарт C++20 -- это тоже отдельная песТня.


            1. rsashka
              26.11.2025 07:21

              Принятие стандарта не означает обязательность его использования.


              1. eao197
                26.11.2025 07:21

                Рано или позно все равно придется переходить.


                1. rsashka
                  26.11.2025 07:21

                  Нужно переходить не тогда, когда "можно", а тогда, когда без новых фич уже нельзя.


                  1. eao197
                    26.11.2025 07:21

                    А могли бы вы мне рассказать, что именно вы пытаетесь до меня донести?


                    1. rsashka
                      26.11.2025 07:21

                      Можно посмотреть в истории:

                      Типа сейчас очень просто взять и после C++14 переучиться на C++26. Ага.

                      Что принятие стандарта не требует его немедленного изучения и обязательного применения.


                      1. eao197
                        26.11.2025 07:21

                        Что принятие стандарта не требует его немедленного изучения и обязательного применения.

                        Т.е. человек 10 лет сидел на C++14, потом пришло время перейти на C++26 и тут вдруг оказалось, что мои слова "Типа сейчас очень просто взять и после C++14 переучиться на C++26. Ага." не соответствуют действительности.

                        Так я и поверил, ага.

                        PS. Вы как-то по своему эту фразу восприняли, я не говорил о том, что стандарты нужно изучать по мере их публикации.


                      1. rsashka
                        26.11.2025 07:21

                        Я написал про то, что использованное вами слово "переучиваться" и сам тон комментария намекает на обязательность переобучения на новый стандарт, тока как я пишу про то, что использование фич из новых стандартов опционально.

                        Более того, например, я точно уверен, что знаю далеко не все фичи и тонкости новых стандартов, но это не мешает мне писать под C++23.


                      1. eao197
                        26.11.2025 07:21

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

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

                        Затем пришлось переучиваться на C++17, т.к. там и structured binding, и if constexpr, и fold expressions.

                        Затем пришлось переучиваться на C++20, т.к. там и концепты и тот же operator<=> (с которым есть неочевидные моменты). Короутины еще. Модули.

                        В C++23 появился deducing this.

                        Так-то смысл перехода на новый стандарт именно в том, чтобы освоить новые трюки и научиться обходиться без старых.

                        Приедет C++26 и нужно будет учиться жить с рефлексией.


                      1. rsashka
                        26.11.2025 07:21

                        Я с вами согласен, что использование новых стандартов обязательно требует из изучения :-)


                      1. KiddingBanana
                        26.11.2025 07:21

                        А минорные фичи типа fold expression и deducing this точно требуют именно переучивания?
                        Имхо, большие изменения были в 11 стандарте, в чуть меньшей степени в 20 и теперь в 26


                      1. eao197
                        26.11.2025 07:21

                        А минорные фичи типа fold expression и deducing this точно требуют именно переучивания?

                        deducing this еще не пробовал. А вот по поводу fold expression у меня регулярно бывают моменты, когда глаза на лоб лезут видя как более опытные в современном C++ люди на fold expression делают то, что я бы делал на функциях с variadic-шаблонами и явной остановкой рекурсии.


                      1. Siemargl
                        26.11.2025 07:21

                        А теперь возьмем обратный вариант - нужно портировать такое на платформу со старым компилятором. И тут упс, а более опытный в современном стандарте уже не помнит, как деды писали =)


                  1. Dooez
                    26.11.2025 07:21

                    Не могу согласиться.

                    Чем дольше оттягивать переход, тем больше кода который не использует новые идиоматические подходы, и больше кода который потенциально будет мешать переходу (хотя это уже маловероятно если не отставать на 9 лет)

                    Переходить на новый стандарт нужно как можно скорее. Это не значит что нужно использовать вообще все его новшества, но наверное в каждом стандарте есть вещи которые упрощают жизнь и имеют крайне низкое трение даже со стороны консервативных коллег.


                    1. rsashka
                      26.11.2025 07:21

                      Переход на новый стандарт не может быть самоцелью, и если приложение и так работает, то зачем его переписывать?

                      но наверное в каждом стандарте есть вещи которые упрощают жизнь

                      так я про это и написал, когда что-то улучшается, упрощается, повышается надежность и т.д.


              1. Jijiki
                26.11.2025 07:21

                но ведь нельзя писать на разных стандартах или можно? щас я наверно минус получу, тогда выходит, если обновилась библиотека "OpenSSL" - язык почти похож на коробку с библиотекой "почти" мне кажется, то на новую версию можно и не переходить, обновление языка, касается и безопасности в том числе, а не просто ради удобства что-то изменилось, поведение кодогенератора может отличаться, может быть улучшена поддержка чего-то, мне кажется новый стандарт как и новая версия или некая стабилити всегда свежесть и выйгрыш, да понимаю, есть килотонны кода, но я так попытался подумать в версии как смог

                Gosling-Emacs вот например уже не собрать без знаний, "потомучто произошли изменения в кодинге" уже те какие всё как мне кажется уже фатальны на этапе сборки


    1. maisvendoo
      26.11.2025 07:21

      Хм, как частота выхода стандартов повлияет на их реализацию компиляторами? Не все фичи C++20 еще пришли в тот же mingw, например. Я не говорю уже про C++23, а на дворе уже 2025 заканчивается. По мне так наоборот - пореже бы их выпускали


      1. NN1
        26.11.2025 07:21

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

        У нас каждый конкретный компилятор в конкретной версии реализуют какую-то часть каких-то стандартов.

        В итоге мы не можем просто взять и ориентироваться полностью на стандарт даже если этого хотим.


      1. eao197
        26.11.2025 07:21

        Хм, как частота выхода стандартов повлияет на их реализацию компиляторами?

        Никак.

        Первая идея вот в чем. Cейчас есть два момента:

        • спешка перед заталкиванием предложения в стандарт перед дедлайном. Грубо говоря, какой-то пропозал почти готов, но если не принять его сейчас, то он войдет лишь в следующий стандарт через 3 года. Поэтому его могут принять даже не смотря на недоделки. Чтобы затем фиксить то, что недосмотрели;

        • долгая пауза между принятием в стандарт и выходом самого стандарта. Допустим, летом 26-го года какую-то фичу примут в С++29. Но формально она станет частью C++ только после принятия C++29. Т.е. в 2029-ом году.

        Если выпускать стандарты раз в год, то тяжесть этих моментов практически нивелируется.

        Вторая идея в том, что если комитет таки начнет синхронизировать то, что попадает в документ с тем, что есть в компиляторах, то частые выпусти релизов позволят чаще синхронизировать состояние компиляторов с текстом стандарта. Грубо говоря, сделают поддержку рефлексии в 3-х основных компиляторах в 2027-ом и тут же можно будет обновить C++27 или C++28. А не ждать принятия C++29.

        Но в то, что комитет как-то начнет синхронизироваться с разработичками компиляторов я уже не верю. Люди нормально живут в своей парадигме, зачем что-то менять?


        1. Zalechi
          26.11.2025 07:21

          Но в то, что комитет как-то начнет синхронизироваться с разработичками компиляторов я уже не верю. Люди нормально живут в своей парадигме, зачем что-то менять?

          В целом поддерживаю ваш комментарий, хотел бы развить в контексте цитаты выше:

          А что если отойти в сторону и воспринимать комитет, как политический орган. По сути ISO это прослойка между Государством (заказчиком) и бизнесом (потребителем). Тогда все встает га свои места:

          Комитет — это международное техническое бюро по стандартизации технологий. Призван регламентировать с одной стороны, давать техническое обеспечение с другой.

          Обожаю пример с ПДД. Мы вынуждены регулировать движение транспортных средств по дорогам общего пользования. Как итог, бизнес производит относительно безопасное современное движение транспортных средств по тем самым дорогам общего пользования.

          Все эти правовые, научно-прдпринимательские отношения решаются в таком порядке. Поэтому лаг.

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

          … или как это работает?


          1. eao197
            26.11.2025 07:21

            Комитет — это международное техническое бюро по стандартизации технологий.

            Интересная аналогия, спасибо.

            Но, имхо, сравнивать лучше не с ПДД. ПДД -- это ближе к каким-нибудь стандартам MISRA.
            А вот ISO-шный стандарт для C++ больше похож на ГОСТы для строительных материалов: типа плиточный клей такой-то, пеноблок такой-то, плита перекрытия такая-то. Т.е., согласованные экспертами спецификации, а уже конкретная продукция, удовлетворяющая этим спецификациям, производится разными заводами стройматериалов.

            Только вот получается, что если тебе нужно построить дом, то ориентироваться приходится не на то, что есть в принципе, а лишь на то, что доступно в ближайшем магазине стройматериалов. И если туда чего-то не завезли, то не судьба -- спецификация живет отдельной жизнью, ассортимент в магазине -- своей :(


            1. Zalechi
              26.11.2025 07:21

              Тоже не плохой пример, но и комитет не всесильный орган, а лишь техническая экспертная группа.

              А вот кто в правительстве следить за соответсвие продукции стандартам — могу только догадываться.


              1. eao197
                26.11.2025 07:21

                Вот поэтому-то и есть идея о том, что комитет вводит дополнительный статус для предложений: готово к включению в стандарт, но еще не реализовано. И такие фичи в текст стандарта не включаются до тех пор, пока не перейдут в статус "готово к включению в стандарт, реализовано".

                Т.о. компенсируется та проблема, что комитет не может повлиять на скорость реализации конкретной фичи в компиляторах. Но зато может формировать стандарт только из тех фич, которые уже реализованы в основных компиляторах.

                От того, что какая-то фича будет ждать своей реализации годами нас это не спасет. Но зато мы точно будем понимать, что если есть условный С++32, то он практически весь реализован в свежих версиях компиляторов. А не как сейчас.

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


                1. Zalechi
                  26.11.2025 07:21

                  понял.


                1. Siemargl
                  26.11.2025 07:21

                  А это было раньше - я помню TR1, и вроде как позже зафиксировали подобный путь развития.


      1. vanxant
        26.11.2025 07:21

        Да вот как раз слона проще есть по частям. Всем будет понятнее "естественный" порядок имплементации фич, типа сначала сделайте 26, а потом уже 27 (который частично зависит от 26).


  1. eao197
    26.11.2025 07:21

    И еще вот такой вопрос: а комитет хоть как-то озадачивается тем, что в реальной жизни есть два C++:

    • описанный в стандарте;

    • доступный обычным разработчикам в конкретных компиляторах.

    Причем одно далеко не всегда соответствует второму. И существует серьезный разрыв по времени между включением чего-то в стандарт и появлением этого же хотя бы в большой тройке компиляторов.

    Пока что есть ощущение, что комитету, мягко говоря, фиолетово. Мол, мы включим в стандарт некую фичу, а когда это доберется до простых смертных (особенно тех, кто вынужден пользоваться разными компиляторами на разных платформах) -- не наши проблемы.

    Я помню каково было ждать, пока нормальная поддержка С++98 в компиляторах появится. А потом поддержка C++11. После чего вот прям благодать настала со стандартами C++14 и C++17. Но вот уже с C++20 опять та же срань :(

    PS. Понимаю, что комитет не управляет разработкой компиляторов в Microsoft, Apple или RedHat. Но хотя бы о таком разрыве говорят?


    1. ZirakZigil
      26.11.2025 07:21

      Пока что есть ощущение, что комитету, мягко говоря, фиолетово

      А как иначе? Ну вот занимает столько-то времени у вендоров выкатить эту фичу, что комитету прикажете делать?


      1. eao197
        26.11.2025 07:21

        А как иначе?

        Мне думается, что если проблема есть, то:

        • начать можно с того, чтобы хотя бы признать ее официально;

        • после ее официального признания можно будет начать искать способы решения.

        Например, можно доработать "train model" по которой ведется развитие стандарта. Скажем, фича N получает статус "одобрена для включения в стандарт". После чего она не включается автоматически в стандарт, а ставится на паузу до тех пор, пока ее драфтовая реализация не появится, например, в gcc+clang+msvc. Когда драфтовая реализация появляется, фича включается в стандарт.

        При этом если при реализации фичи обнаруживаются подводные камни, то все это решается без оглядки того, что фича N уже отлита в граните включена в стандарт.


        1. ZirakZigil
          26.11.2025 07:21

          Нет способов решения проблемы вида: "мы можем выкатить эту фичу не меньше чем за N времени" — кроме как выкатив её самому быстрее (для опен сорсных решений), или проспонсировав её форсирование (удачи проспонсировать майкрософт).

          Когда драфтовая реализация появляется, фича включается в стандарт.

          Что это изменит на практике в вопросе ожидания? Мне, как пользователю, ни тепло, ни холодно от того, в какой момент на бумаге что-то появилось.


          1. eao197
            26.11.2025 07:21

            Нет способов решения проблемы вида: "мы можем выкатить эту фичу не меньше чем за N времени"

            А я и не предлагаю решать эту проблему.

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

            Что это изменит на практике в вопросе ожидания?

            Чуть меньше чем все, наверное.

            Сейчас вот в стандарте есть std::start_lifetime_as, на практике ее нет.
            Ну и что мне с этим делать? Писать какие-то свои заглушки, который будут затем развернуты в актуальный вызов std::start_lifetime_as когда он появится.

            А так нет start_lifetime_as в большой тройке, и в стандарте ее нет.


            1. ZirakZigil
              26.11.2025 07:21

              А я и не предлагаю решать эту проблему

              Т.е. вы предлагаете просто позаниматься канцелярскими делами. Зачем на это тратить время, правда, не очень понятно.

              Чуть меньше чем все, наверное.

              Ничего. В обоих случаях я не могу использовать start_lifetime_as . А когда она появится, то в обоих случаях я смогу её использовать в один момент времени.


              1. eao197
                26.11.2025 07:21

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

                Во-первых, я ничего не предлагаю. Всего лишь интересуюсь рассматривают ли в комитете сложившуюся ситуацию как проблему или нет.

                Во-вторых, не понимаю, откуда вы сделали такой вывод. Сейчас судьба пропозала такова: пропозал вносится, над ним работают, затем его признают готовым к включению, после чего он входит в стандарт и, если нужно, далее вносятся правки.

                Можно сделать так, что когда пропозал объявляют готовым к принятию в стандарт, то он не вносится в стандарт сразу. А дожидается пока его реализуют. Только после этого его текст вновится в стандарт.

                Дополнительный плюс здесь в том, что если в процессе реализации обнаруживаются подводные камни (вот как в случае с trivial relocatable), то не нужно ничего из стандарта отзывать или вносить в стандарт корректирующие правки.

                В обоих случаях я не могу использовать start_lifetime_as

                Тогда у меня нет ответа на вопрос: зачем иметь в стандарте C++23 фичу, которой нельзя пользоваться на практике в конце 2025-го года?

                Меня лично, за 30 лет с C++, эта ситуация очень забодала. Не так конечно, как необходимость использовать CMake, но все-таки. В 1990-е еще было понятно ради чего ждать, типа первый стандарт, в мире C++ ничего подобного еще не было. Но с момента принятия первого стандарта уже 27 лет прошло. А мы как будто бы ничему не учимся.


                1. ZirakZigil
                  26.11.2025 07:21

                  зачем иметь в стандарте C++23 фичу, которой нельзя пользоваться на практике в конце 2025-го года?

                  Вам от этого ни тепло, ни холодно, зачем этим вопросом вообще задаваться? Если фичу обозначили как "надо" в N году, а сделали в N+3, то вы сможете ей пользоваться только в N+3 году, независимо от того, внесли ли её в стандарт в году N, или в году N+3.


                  1. eao197
                    26.11.2025 07:21

                    Вам от этого ни тепло, ни холодно, зачем этим вопросом вообще задаваться?

                    Вот это сейчас странный заход, ейбоху.

                    Возьмем std::launder. До C++17 мы тупо сажали в код UB. После C++17 делать какие-то вещи без std::launder -- это опять же сажать в код UB. Но тут как бы есть джентельменская договоренность -- компиляторщики не эксплуатируют этот UB пока мы в предыдущих стандартах. Но если мы в C++17 (20, 23), но не используем std::launder, то сами себе злобные буратины.

                    Аналогично с start_lifetime_as. Без этого, если мы выставили С++23 как стандарт, мы не имеем права делать какие-то вещи, ибо UB. Значит нужно использовать start_lifetime_as. А его нет. Вот тупо нет. Ключик -std=c++23 есть, часть фич из C++23 есть, а нужного мне нет.

                    Аналогично можно и с [[no_unique_address]] ситуацию вспомнить. Как бы в стандарте он есть и давно. А вот в компиляторах -- как повезет.

                    Повторюсь: тут я не понимаю смысла происходящего. В стандарте есть фича, у меня в проекте включен стандарт, но этой фичи нет.

                    Тогда зачем мне подобный стандарт, если все равно приходится смотреть на фактическое наличие в компиляторе? Зачем включать в стандарт то, что затем по 3 года не может стать доступным для пользователя?

                    Плохо здесь то, что вот нужен мне start_lifetime_as, а его нет в наличии. Я наговнякую с UB и этот говнокод затем будет жить годами, потому что про него все забудут. А в какой-то момент комплятор начнет эксплуатировать данный UB и придется кому-то искать что и почему. Хотя, если я сейчас в рамках С++23 код пишу, то почему не имею возможности использовать то, что в стандарте описано?


                    1. ZirakZigil
                      26.11.2025 07:21

                      Какая разница НА ПРАКТИКЕ, вы можете ответить? Вот было бы как вы хотите, был бы у вас не -std=c++23 без start_lifetime, а был бы -std=c++2x_ver_26_05_2025 без start_lifetime. Суть-то не изменилась: start_lifetime всё равно нет.

                      В стандарте есть фича, у меня в проекте включен стандарт

                      Так это вопрос к вендору. Ответственный вендор назовёт c++2a\b\c\d или c++latest, намекая, что стандарт полностью не поддерживается.

                      Я наговнякую с UB

                      Ваши действия — ваша ответственность, не нужно её перекладывать на комитет или вендора.


                      1. eao197
                        26.11.2025 07:21

                        Какая разница НА ПРАКТИКЕ, вы можете ответить?

                        На какой практике?

                        Я вам вот о чем говорю: в стандарте фича есть, в комиляторах ее нет. Это продолжается не с одной фичей и не один год. Вопрос к комитету: комитет считает это нормальным или нет?

                        Так это вопрос к вендору.

                        Тут можно посмотреть с точки зрения пользователя: мне без разницы что есть отдельно комитет, отдельно вендоры, мне код писать нужно. Для этого мне нужна фича, которая в стандарте есть, а в компиляторах нет. И мне, как пользователю, хочется посоветовать комитету: ребяты, а могли бы вы построить свою работу так, чтобы в стандарт входило только то, что в компиляторах уже реализовано?

                        Нет? Точно нет? Точно точно?

                        Ну раз точно, тогда продолжим жрать кактус.

                        Ваши действия — ваша ответственность, не нужно её перекладывать на комитет или вендора.

                        Прекрасно. Есть проект, который уже в рамках C++23.
                        В какой-то части проекта мне нужно написать что-то вроде:

                        const std::byte * data_fragment = ...;
                        const std::size_t payload_offset = calculate_payload_offset(data_fragment);
                        const auto * payload = std::start_lifetime_as<const data_payload *>(
                          data_fragment + payload_offset); 
                        

                        В рамках C++23 получение указателя на data_payload без start_lifetime_as -- это UB, насколько мне известно.

                        Вопрос: как мне быть в этой ситуации?


                      1. ZirakZigil
                        26.11.2025 07:21

                        На какой практике?

                        Это когда я открыл IDE и пытаюсь написать std::start_lifetime_as. Если её нет, то её нет, и от того, что в параметрах компилятора написано не -std=c++23, а -std=c++2x_27_11_2025 мне ни тепло, ни холодно.

                        И мне, как пользователю, хочется посоветовать комитету: ребяты, а могли бы вы построить свою работу так, чтобы в стандарт входило только то, что в компиляторах уже реализовано?

                        И сколько ждать нужно? Пока все компиляторы не напишут?

                        Вопрос: как мне быть в этой ситуации?

                        Также как вы были прошлые 30 лет? Или вам первый раз понадобилось превратить набор байт в какую-то структурку, а тут подлый комитет палки в колёса вставил?

                        А вообще, p0593 существует. Так что пользуйтесь pre-c++23 вариантомstd::launder(static_cast<T*>(std::memmove(p, p, sizeof(T))));


                      1. eao197
                        26.11.2025 07:21

                        Это когда я открыл IDE и пытаюсь написать std::start_lifetime_as. Если её нет, то её нет, и от того, что в параметрах компилятора написано не -std=c++23, а -std=c++2x_27_11_2025 мне ни тепло, ни холодно.

                        Вы, видимо, упорно игнорируете то, что я вам пишу про пример с start_lifetime_as. Ну ОК, кроме вашего упрямства это больше ничего не демонстрирует.

                        И сколько ждать нужно?

                        Сколько нужно. Люди вот годами ждут сеть и экзекуторов в стандарте. Ждут и ждут, ждут и ждут.

                        А потом будут ждать и ждать появления в компиляторах.

                        Так что ничего принципиально не изменится: ждать придется столько, сколько нужно, а сколько нужно никто не знает.

                        Пока все компиляторы не напишут?

                        В идеале. Но меня бы лично устроила большая тройка (особенно с учетом того, что часть ранее независимых компиляторов перешла на LLVM/clang).

                        Так что пользуйтесь pre-c++23 вариантом std::launder(static_cast<T*>(std::memmove(p, p, sizeof(T))));

                        Да я-то сколько угодно разных костылей могу в код напихать. При этом у меня нет уверенности в том, что использование std::launder здесь корректно начинает лайфтайм для объекта (и начинает ли вообще).

                        Вопрос в другом: считает ли комитет такую ситацию нормальной?

                        PS. Ну и есть более сложные случаи, вроде [[no_unique_address]], которые так просто не объедешь.


    1. antoshkka Автор
      26.11.2025 07:21

      После чего вот прям благодать настала со стандартами C++14 и C++17. Но вот уже с C++20 опять та же

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

      В С++23 и C++26 нет таких "монстров", так что должно всё гладко идти и вендоры быстро наверстают отставание


      1. rsashka
        26.11.2025 07:21

        С C++20 основная засада - модули

        Если я правильно запомнил тезисы твоего выступления на C++ Zero Cost Conf про модули ,то там основная засада, это макросы препроцессора.

        Хотелось бы услышать твое мнение насчет этого предложения, которое должно решать проблемы модулей с макросами и сохраняет обратную совместимость со старым кодом.


        1. antoshkka Автор
          26.11.2025 07:21

          Международный комитет выступил против подобной идеи https://github.com/cplusplus/papers/issues/2316

          Если хочется продолжить работу - нужна новая, более внушительная, мотивация


          1. rsashka
            26.11.2025 07:21

            Это совершенно другое предложение, которое наоборот запрещает экспорт макросов из модулей и добавляет обработку имен макросов в С++ модулях на уровне AST, а не только во время работы препроцесоора.


            1. antoshkka Автор
              26.11.2025 07:21

              Идея https://github.com/cpp-ru/ideas/issues/622 предлагает экспортировать макросы из global module fragment для именованных модулей. https://github.com/cplusplus/papers/issues/2316 предлагал то же самое

              Та часть вашего предложениея, что

              #define MACRO_LOCAL macro_local
              
              import mod; // В модуле mod видны оба макроса  MACRO_GLOBAL и MACRO_LOCAL

              никак не сможет работать с модулями. Именованный модуль уже "запечён", и в него ничего больше не прилетает. Такой модуль - это практически иммутабельный бинарный блоб. Что-то схожее предлагалось в https://github.com/cplusplus/papers/issues/2316 и комитет был против


              1. rsashka
                26.11.2025 07:21

                Данный пример не принципиальный и не является ключевым. Ведь новое поведение может быть каким угодно, и раз модуль "уже "запечён", и в него ничего больше не прилетает. ", тогда пусть локальные макросы модуля будут доступны только внутри компилируемого модуля, а в импортируемых модулях недоступны.

                Поправил описание предложения

                Что-то схожее предлагалось в https://github.com/cplusplus/papers/issues/2316 и комитет был против

                Это совершенно другое предложение, которое наоборот запрещает экспорт макросов из модулей и добавляет обработку имен макросов в С++ модулях на уровне AST, а не только во время работы препроцесоора.


                1. antoshkka Автор
                  26.11.2025 07:21

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


                  1. rsashka
                    26.11.2025 07:21

                    В данном случае никакой новый функционал не добавляется и основная задача предложения - это не сломать старое поведение мароксов в легаси коде (с их обработкой только в препроцессоре)

                    Но так как макросы действительно ломают логику в С++ модулях, то формально макросы остаются, (чтобы не получить негатив от приверженцев старого С++), но их поведение в модулях меняется, так как добавляется дополнительный анализ на уровне AST. Фактически это плавный переход от макросов препроцессора к будущей рефлексии, т.к. с помощью последней можно сделать примерно тоже самое.

                    но слишком много нюансов и проблем возникает, пока кажется что овчинка не стоит выделки

                    Я могу сделать пример реализации этой фичи с помощью clang плагина, чтобы была возможность проверить предложенное поведение на реальном коде, но вряд ли смогу понять её применимость для С++ модулей, так как не знаю всех их тонкостей и нюансов.


                    1. antoshkka Автор
                      26.11.2025 07:21

                      В данном случае никакой новый функционал не добавляется и основная задача предложения - это не сломать старое поведение мароксов в легаси коде (с их обработкой только в препроцессоре)

                      Но ведь макросы и так можно использовать в именованных модулях в global module fragment и они прорастают ниже в module unit, и за его пределы не экспортируются.

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


                      1. rsashka
                        26.11.2025 07:21

                        Для того, чтобы с помощью макросов препроцессора нельзя было переопределять интерфейс модуля (изменять имена экспортируемых классов и функций).


                      1. antoshkka Автор
                        26.11.2025 07:21

                        А почему почему вы хотите это запрещать? Например многие проекты используют макрос, чтобы задать namespace и inline namespace с версией. С вашим предложением этот функционал перестанет работать


                      1. rsashka
                        26.11.2025 07:21

                        Пускай задают, на внутренне поведение это никак не влияет.

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


                      1. antoshkka Автор
                        26.11.2025 07:21

                        Именно на публичный интерфейс и влияет макрос для namespace, так что сломается :(


                      1. rsashka
                        26.11.2025 07:21

                        Но ведь именно эту проблему ты и озвучивал в своем докладе (потенциальная зависимость интерфейса модуля от макросов времени компиляции), но если этой проблемы не существует, тогда мое предложение действительно не имеет смысла.

                        Если же такая проблема все же присутствует, тогда её можно решить добавлением анализа имен макросов после построения AST, но вот в каких местах это нужно делать, я со 100% точностью сказать не смогу.

                        Если ты считаешь, что раскрытие макросов в namespace допускаются, пусть будет так. Как я уже сказал, я не знаю всех тонкостей использования модулей и не вижу смысла спросить со специалистом.


  1. LinkToOS
    26.11.2025 07:21

    встречи ISO C++ на Гавайях

    Как там погода, на Гавайах?
    Почему статья без фотографий? Стоило ли собираться на Гавайях, если нет классных фоток?

    Какой вообще смысл в таких тусовках? Что там происходит такого, чего нельзя решить с помощью телеконференций и дистанционного голосования?


    1. antoshkka Автор
      26.11.2025 07:21

      Как там погода, на Гавайах?

      Не в курсе, я удалённо участвовал :)

      Но не удивлюсь, если офлайн участники тоже не знают какая там погода - обычно времени на осмотр окресностей нет, график очень плотный, а в больших аудиториях с окнами зачастую напряжёнка

      Какой вообще смысл в таких тусовках?

      Основной смысл - общий сбор, точка синхронизации и формального голосования. Онлайн тоже есть, но встреча работает эффективнее


    1. rivo
      26.11.2025 07:21

      На таких встречах тайно договариваются, как сделать чтобы язык был максимально сложным. В стандарте С++36, добавят обязательное чтение мантры для успещного запуска программы, чтобы LLM не смогла писать код вместо человека. Смыслом жизни станет изучение и трактовка стандартов. Подготовку специалистов перенесут в закрытые монастыри.


      1. Belarus
        26.11.2025 07:21

        *C++35


  1. Notevil
    26.11.2025 07:21

    В P1789 std::integer_sequence обзавёлся методами, позволяющими использовать его в structured binding и template for:

    И я вдруг понял, что этого всю жизнь не хватало.

    Но еще жизнь надо будет подождать, пока я на 26 стандарт перейду.


  1. domix32
    26.11.2025 07:21

    В частности, на этом заседании не дошли руки до P3725, который делает надёжный и безопасный std::ranges::filter, не подверженный проездам по памяти и Segmentation Fault в примерах наподобие:

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

    Отдельно вопрос - а не думал ли кто-нибудь сделать альтернативные API на опционалах по аналогии ржавых?


    1. antoshkka Автор
      26.11.2025 07:21

      альтернативные API на опционалах

      Вроде бы уже всё есть. Можете пожалуйста привести пару примеров, чего не хватает?


      1. ZirakZigil
        26.11.2025 07:21

        Подозреваю, речь про что-то типа optional<T> find().


      1. domix32
        26.11.2025 07:21

        В std примерно нигде не используются опционалы, насколько мне известно. Везде итераторы и сентинелы в лучшем случае.

        Любой из find API (хоть на строках, хоть на рэнжах) возвращает либо индекс (по старой сишной традиции -1 для "не найдено"), либо итератор и я пока не видел чтобы хоть кто-то вернул std::optional или std::expected. Хотя казалось бы логичным писать что-то вроде

        if (auto result = haystack.find(needle)) {}

        В API контейнеров есть места, где возвращаются пары, где одно из значений - успех выполнения команды - std::unoredered_map<K,V>::insert(), например. Кажется адекватное применение для опционалов. Штуки типа std::from_chars - самое оно для expected. .at тоже нигде не возвращает опционалов, то есть нет ни одного такого noexcept аксессора - будь-то контейнер, span или строка.

        По-хорошему иметь дубликат всех APi которые кидают исключения в виде опциональных вариантов.

        Отдельно наверное стоит спросить за перегрузки с автоматическим приведением контейнеров к range в алгоритмах, чтобы тот же find писать std::find(container, predicate), а не писать границы каждый раз ну и соотвественно иметь возможность делать что-нибудь а ля

        auto range = container
          |filter([]{...})
          |transform([]{...});
        std::find(range, predicate);

        Ествественно одним только find не ограничиваться, но и прочие подходящие алгоритмы тоже.

        Отдельно - API для взаимодействия итераторов - chain, zip, cycle и прочие.


        1. KanuTaH
          26.11.2025 07:21

          Кажется адекватное применение для опционалов.

          Каким образом? Там же итератор возвращается всегда, независимо от того, был уже этот элемент в контейнере или нет, в этом весь смысл такого API.


          1. domix32
            26.11.2025 07:21

            По аналогии с ржавым. А обновление делать через какой-нибудь insert_or_update(). Собственно. поэтому вопрос про альтернативные API, типа как flux сделал, оставив некоторый слой совместимости с UB из std, ибо воткнуть их в текущую реализацию без горожения ещё большего ахтунга кажется нереально.


            1. KanuTaH
              26.11.2025 07:21

              Сейчас очень частая задача вида "если элемента с таким-то ключом еще нет в мапе, то вставить начальное значение, если он есть - то инкрементировать его на N" благодаря текущему API решается за один лукап. Продемонстрируйте, пожалуйста, как такая задача будет решаться за один лукап "по аналогии со ржавым" или "через какой-нибудь insert_or_update()", а то лично мне например непонятно, в чем состоит идея и как эта идея что-то реально улучшит, за исключением "перехода на опционалы ради перехода на опционалы".


              1. domix32
                26.11.2025 07:21

                то инкрементировать его на N"

                В Rust такая задача решается как-то так:

                map
                .entry(key)
                .and_modify(|v| *v += N)
                .or_insert(value);

                entry соотвественно вернёт обёртку над значением внутри контейнера, которое вы вольны обновить как вам угодно, если оно существовало. Иначе вставляете ваше желаемое значение.

                В С++ вы всё это вытворяете ручками.

                auto [it, ok] = map.insert({key, value});
                if (!ok) {
                  it->second += N;
                }
                // ну раз мы итератор, то давай ещё и пошагаем
                it++; // при желании можем выстрелить себе в ногу
                      // за единственный же лукап

                Минусы

                • метапотроха мапы становятся чуть более публичными в сравнении с голыми итераторами и чуть менее универсальными

                • нельзя переключиться на следующие элементы в контейнере (есть юзкейс?)

                • контейнеры с++ для такого надо будет переделывать

                Плюсы:

                • инкапсуляция намерений - обновление и вставка две разные операции, понятнее, что хотел сказать автор, да ещё и из коробки

                • избавляемся от потенциальных UB - ни .end()++ ни *.end() исполнить не получится.

                Ну а основная цель перехода на опционалы - переход к noexcept и локализация обработки ошибок ближе к собственно местам потенциальных ошибок, а не где-то на 10 уровней выше по стеку со всеми проблемами разворачивания стека.


                1. KanuTaH
                  26.11.2025 07:21

                  В Rust такая задача решается как-то так:

                  А вы уверены, что решается именно эта задача? Я вот сейчас не поленился, написал тест с вырожденной хеш-функцией, намеренно создающей коллизии. И что-то как только я комментирую часть .or_insert(i), так сразу время выполнения примерно вдвое падает. Ну прямо очень похоже на отдельный лукап на вставке. Да и с чисто технической стороны вопроса, из описания всех этих or_insert следует, что они выполняют полноценную операцию вставки, включая лукап. Иначе согласно этому API бы приходилось сначала всегда вставлять какой-то элемент в букет, если элемента с соответствующим ключом нет, а если or_insert не вызван, то приходилось бы его удалять при уничтожении экземпляра Entry, верно? А если вставляемый экземпляр невозможно создать со значениями "по умолчанию", как быть? Вопросы, вопросы...

                  P.S. Есть конечно вариант не вставлять "пустое" значение, а просто найти букет и держать его, но тогда получается, что ты не можешь найти Entry, потом что-нибудь сделать с map (скажем, вставить что-то или удалить), а потом сделать что-то с сохраненной Entry. В расте эта проблема "решается" тем что Entry "одалживает" map в свое полное распоряжение, и ты ничего не сможешь с этим map сделать, пока экземпляр Entry не уничтожится. Ну, тоже такое себе в приложении к C++.


                  1. domix32
                    26.11.2025 07:21

                    The hash table implementation is a Rust port of Google’s SwissTable.

                    я не знаю как конкретно этот swiss table резолвит коллизии. И не понимаю почему or_insert триггерит пессимизацию производительности в дебаге учитывая, что там обычный матч по собственному состоянию.

                    то приходилось бы его удалять при уничтожении экземпляра

                    да, каждая из API ожидаемо делает то что вы предполагаете. Entry не делает грязи как плюсовые квадратные скобки.

                    А если вставляемый экземпляр невозможно создать со значениями "по умолчанию", как быть?

                    То вы его самостоятельно конструируете и отдаёте в функцию вставки. В Rust по-умолчанию везде перемещение, а не копирование так что оно практически in place конструируется.

                    map
                    .entry(key)
                    .or_insert(NonDefaultConstructible::new(/*args*/))

                    Есть конечно вариант не вставлять "пустое" значение, а просто найти букет и держать его

                    это уже всё детали реализации, которые я не читал. В гугловых тоже не смотрел. Можете попробовать сравнить cpp с rust и посмотреть будет ли там деградация на коллизиях. Abseil можно подключить на godbolt.


                    1. KanuTaH
                      26.11.2025 07:21

                      И не понимаю почему or_insert триггерит пессимизацию производительности в дебаге учитывая, что там обычный матч по собственному состоянию.

                      Ну так-то в данном конкретном месте матч, да, но потом через десятые руки в hashbrown::hash_map вызывается вот такое:

                      impl<'a, T, A> VacantEntry<'a, T, A>
                      where
                          A: Allocator,
                      {
                          pub fn insert(self, value: T) -> OccupiedEntry<'a, T, A> {
                              let bucket = unsafe {
                                  self.table
                                      .raw
                                      .insert_tagged_at_index(self.tag, self.index, value)
                              };
                              OccupiedEntry {
                                  bucket,
                                  table: self.table,
                              }
                          }
                      }

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

                      Можете попробовать сравнить cpp с rust и посмотреть будет ли там деградация на коллизиях.

                      В текущем C++ API деградации на коллизиях просто неоткуда взяться, так как после единственного лукапа при insert мы сразу получаем итератор, указывающий на конкретную прямо KV-пару, и все на этом, дальше работа идет просто с этой KV-парой напрямую. Можно вообще взять на нее ссылку сразу, никто не мешает. Там все ясно и понятно. У раста же многое зависит от качества реализации вот этой прослойки всей, нужно с бутылкой засесть и потеть, если хочешь разобраться, не факт что какие-нибудь умельцы чего-нибудь не пессимизируют потом... Ну и конечно тот факт что Entry пожирает всю мапу до конца своего лайфтайма, тоже мягко говоря, не очень удобно.


                      1. domix32
                        26.11.2025 07:21

                        Так вы сравниваете производительность разных имплементаций. Стандартный контейнер раньше при коллизиях вырождался в список со длинющим линейным лукапо со всеми вытекающими. Ситуацию вроде несколько улучшили, но всё равно просадка на коллизиях имеет место быть и тут не сильно принципиально, что он единственный. Гугловая табличка из abseil должна делать примерно то же самое, что и ржавая и оба делают SIMD-оптимизации лукапов, так что оно даже если с двойным лукапом должно получится быстрее чем стандартный лукап в std::umap/std::uset. Ну, а считать производительность на вырожденных случаях в дебаге несколько странное занятие.


                      1. KanuTaH
                        26.11.2025 07:21

                        Ну, а считать производительность на вырожденных случаях в дебаге несколько странное занятие.

                        Меня главным образом интересовало, сколько лукапов делает реализация через эти Entry в расте, и было две альтернативы - сидеть с бутылкой и разбирать внутренности Entry или по-быстрому попробовать грубо оценить через тайминги на вырожденном случае. Ну хотя внутренности все равно пришлось разбирать.


                1. Kelbon
                  26.11.2025 07:21

                  это апи в крабовый язык добавлено исключительно потому что по другому невыразимо в так называемом safe подмножестве. То есть другими словами это костыль с оверхедом и абсолютно нечитаемый.

                  И вы предлагаете костыль перетащить в язык, где всё сделано логично и правильно


                  1. domix32
                    26.11.2025 07:21

                    костыль с оверхедом и абсолютно нечитаемый.

                    вот тут я бы попросил пруфов. и за оверхэд и за нечитаемость.

                    И вы предлагаете костыль перетащить в язык

                    Я ничего не предлагаю. Я хочу, чтобы язык развивался для людей и не позволял отстреливать ногу при использование стандартной библиотеки.

                     где всё сделано логично и правильно

                    видимо поэтому глупые людишки переизобретают стандартные контейнеры во всяких Abseil, Eastl и Beman. То ли дело комитет, который логично сначала депрекейтит вещи, потом следом раздепрекейчивает их в следующем стандарте и превращает простые и чистые пропозалы в нагромождение спецсимволов, потому что проще поменять стандарт, чем компилятор (см. первые пропозалы по pattern matching и как оно выглядит сегодня). Ну и проблема option<T&> конечно же возникла не из-за костыля, а идиоматическая несовместимости. Казалось бы никто и подумать не могу, что люди попытаются провернуть такой трюк.


                  1. feelamee
                    26.11.2025 07:21

                    То есть другими словами это костыль с оверхедом и абсолютно нечитаемый.

                    добавлю что эти коллбэки ещё и значительно усложняют дебаггинг


        1. NN1
          26.11.2025 07:21

          Откройте std::ranges алгоритмы.

          Как раз то, что просили без итераторов

          https://en.cppreference.com/w/cpp/algorithm/ranges/find.html


          1. Yaring
            26.11.2025 07:21

            С одной стороны да. std::ranges позволяют написать вместо

            auto it = std::find(long_container_name.begin(), long_container_name.end(), element_to_find);  
            if (it != long_container_name.end()) { ... }

            написать

            auto it = std::ranges::find(long_container_name, element_to_find);  
            if (it != long_container_name.end()) { ... }

            спасибо и на этом. Но удобная вариация с std::optional, сделанная для людей позволила бы писать так:

            auto it = std::ranges::try_find(long_container_name, element_to_find);  
            if (it) { ... }

            А если оно будет сразу в контейнере, то так:

            auto it = long_container_name.try_find(element_to_find);  
            if (it) { ... }

            и это никак не ломает существующий код.

            it может быть как std::optional от объекта, так и от итератора - тут уж не знаю как правильнее. Но это позволит не писать название вектора три! раза, чтобы выполнить самую базовую операцию.


            1. NN1
              26.11.2025 07:21

              А если возвращать итераторы то можно просто использовать их сразу в алгоритме.

              erase(find(c ,p), c.end())

              Как вариант можно было сразу работать везде с отрезками как в D:

              https://dlang.org/library/std/range.html

              https://www.informit.com/articles/printerfriendly/1407357


              1. Yaring
                26.11.2025 07:21

                Ну я же не отрицаю возврат итераторов. Просто он удобен не во всех сценариях, поэтому и хотелось бы иметь ряд удобных встроенных функций с возвратом optional поверх API на итераторах.


  1. pavlushk0
    26.11.2025 07:21

    "Trivial relocation в С++26 не будет" - и слава богу, прогнули Bloomberg. Этот уродливый trivial_relocatable_if_eligeable какой то отдельный сорт булшита, кому пришла идея даже рассматривать такое.


  1. Persik1
    26.11.2025 07:21

    Полировка идёт, а больные места по-прежнему на паузе. Вроде движемся, но как-то очень аккуратно и без амбиций


    1. antoshkka Автор
      26.11.2025 07:21

      А какие именно больные места?


      1. pavlushk0
        26.11.2025 07:21

        Сеть осталась, асинхронный ио


  1. buldo
    26.11.2025 07:21

    Вроде хотели что-то стандартное сделать для управления/объявления/обнаружения зависимостей. Есть новости?


    1. antoshkka Автор
      26.11.2025 07:21

      Пока новостей нет. Работа идёт в https://wg21.link/p3286 , но там пока очень далеко до финала


  1. habr_skatilsa
    26.11.2025 07:21

    какой шанс увидеть в C++ properties как в C#?


    1. eao197
      26.11.2025 07:21

      Можно предположить, что после появления рефлексии кому нужны properties смогут воплотить свои хотелки в жизнь самостоятельно.


      1. habr_skatilsa
        26.11.2025 07:21

        костыли и сейчас есть, хотелось бы по нормальному


        1. eao197
          26.11.2025 07:21

          Я к тому, что properties -- это одна из самых спорных штук из тех, что хотелок, которые люди высказывали. На моей памяти любители properties говорят об этом с середины 1990-х, более того, ЕМНИП, Borland и Microsoft добавляли их поддержку в свои С++компиляторы в то время в виде нестандартных расширений языка.

          Прошло 30 лет, никто от отсутствия properties не умер. А кто-то (вроде меня) и вообще не хотел бы их в языке видеть. Так что вероятность их добавления, имхо, крайне низкая.

          Зато через рефлексию все любители этих самых properties смогут обеспечить себе свое личное щасте с большой буквы "Ща" ;)


          1. habr_skatilsa
            26.11.2025 07:21

            кто их не хочет видеть, может их не использовать


            1. eao197
              26.11.2025 07:21

              Но зачем усложнять работу компиляторостроителям ради фичи, которую не будут использовать, скажем, 90% пользователей языка?

              У Страуструпа несколько лет назад было хорошее послание к комитету под названием "Вспомните Vasa": https://www.stroustrup.com/P0977-remember-the-vasa.pdf


              1. habr_skatilsa
                26.11.2025 07:21

                Откуда вообще такая статистика? 90%, а может 89%? Кто-то помер там от отсутствия фич языка, а кто-то не помер? Может попытаемся вести адекватный диалог?


                1. eao197
                  26.11.2025 07:21

                  Откуда вообще такая статистика? 90%, а может 89%?

                  Это не статистика, вы не обратили внимания на слово "скажем" в моем предложении.

                  Но если вы хотите убедить комитет в важности такой фичи, как properties, то вы можете как-то собирать такую статистику и продемонстрировать.

                  Так же после появления рефлексии вы можете написать прототип и на реальных примерах показать как хорошо решаются те или иные проблемы.

                  Кто-то помер там от отсутствия фич языка, а кто-то не помер?

                  Сам факт того, что за последние 30 лет огромное количество софта было написано на C++ без properties доказывает, что это не критичная штука.

                  При этом те же самые 30 лет показывают, что по каким-то темам накапливается критическая масса пожеланий для внедрения новых фич (variadic templates, lambdas, if constexpr, concepts, compile-time reflection, ...). Т.е. по этим направлением выгода от новых фич достаточно очевидна.

                  По поводу properties большие сомнения. Но вы можете их попробовать развееть.

                  Может попытаемся вести адекватный диалог?

                  Да я как бы уже. Но адекватные не означает, что здесь будут озвучиваться вещи которые удовлетворят вас.


                  1. habr_skatilsa
                    26.11.2025 07:21

                    а, ну слово "скажем" все меняет конечно, тогда скажем, что эта фича нужна 99% пользователям, а те штуки, про которые вы тут ноете в комментариях скажем никому кроме вас не нужны, так что все нормально


                    1. eao197
                      26.11.2025 07:21

                      а, ну слово "скажем" все меняет конечно

                      Вы не поверите...


                      1. habr_skatilsa
                        26.11.2025 07:21

                        поверил, воспользовался


                  1. habr_skatilsa
                    26.11.2025 07:21

                    сразу в карму срать побежало обиженное) ну ты же само писало "раз не помер, значит не сильно то и надо" )


                    1. eao197
                      26.11.2025 07:21

                      Любезный, я практически никогда не ставлю минусы на Хабре. За все время присутствия здесь минусов от меня для статей/комментариев наберется всего с десяток. А минусов в карму не было вообще никогда.

                      В этом обсуждении я ни одного минуса никому не поставил.

                      Но пруфов не будет, придется поверить на слово.


                      1. habr_skatilsa
                        26.11.2025 07:21

                        Почему придется? у меня нет выбора поверить или не поверить? А почему?