
Привет! На связи Антон Полухин из Техплатформы Городских сервисов Яндекса. Сегодня я расскажу о ноябрьской встрече Международного комитета по стандартизации языка программирования 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, задать им вопросы, узнать что-то новое и интересное.
22 ноября → YADRO System Level Meetup;
15 декабря → Встреча РГ21.
Буду рад встрече!
P.S.: некоторые ссылки на P???? документы могут ещё не работать, т.к. они не опубликованы. Со временем ссылки заработают
Комментарии (107)

eao197
26.11.2025 07:21И еще вот такой вопрос: а комитет хоть как-то озадачивается тем, что в реальной жизни есть два C++:
описанный в стандарте;
доступный обычным разработчикам в конкретных компиляторах.
Причем одно далеко не всегда соответствует второму. И существует серьезный разрыв по времени между включением чего-то в стандарт и появлением этого же хотя бы в большой тройке компиляторов.
Пока что есть ощущение, что комитету, мягко говоря, фиолетово. Мол, мы включим в стандарт некую фичу, а когда это доберется до простых смертных (особенно тех, кто вынужден пользоваться разными компиляторами на разных платформах) -- не наши проблемы.
Я помню каково было ждать, пока нормальная поддержка С++98 в компиляторах появится. А потом поддержка C++11. После чего вот прям благодать настала со стандартами C++14 и C++17. Но вот уже с C++20 опять та же срань :(
PS. Понимаю, что комитет не управляет разработкой компиляторов в Microsoft, Apple или RedHat. Но хотя бы о таком разрыве говорят?

ZirakZigil
26.11.2025 07:21Пока что есть ощущение, что комитету, мягко говоря, фиолетово
А как иначе? Ну вот занимает столько-то времени у вендоров выкатить эту фичу, что комитету прикажете делать?

eao197
26.11.2025 07:21А как иначе?
Мне думается, что если проблема есть, то:
начать можно с того, чтобы хотя бы признать ее официально;
после ее официального признания можно будет начать искать способы решения.
Например, можно доработать "train model" по которой ведется развитие стандарта. Скажем, фича N получает статус "одобрена для включения в стандарт". После чего она не включается автоматически в стандарт, а ставится на паузу до тех пор, пока ее драфтовая реализация не появится, например, в gcc+clang+msvc. Когда драфтовая реализация появляется, фича включается в стандарт.
При этом если при реализации фичи обнаруживаются подводные камни, то все это решается без оглядки того, что фича N уже
отлита в гранитевключена в стандарт.
ZirakZigil
26.11.2025 07:21Нет способов решения проблемы вида: "мы можем выкатить эту фичу не меньше чем за N времени" — кроме как выкатив её самому быстрее (для опен сорсных решений), или проспонсировав её форсирование (удачи проспонсировать майкрософт).
Когда драфтовая реализация появляется, фича включается в стандарт.
Что это изменит на практике в вопросе ожидания? Мне, как пользователю, ни тепло, ни холодно от того, в какой момент на бумаге что-то появилось.

eao197
26.11.2025 07:21Нет способов решения проблемы вида: "мы можем выкатить эту фичу не меньше чем за N времени"
А я и не предлагаю решать эту проблему.
Я предлагаю решать другую: формально включать в стандарт только то, что есть хотя бы в основных компиляторах.
Что это изменит на практике в вопросе ожидания?
Чуть меньше чем все, наверное.
Сейчас вот в стандарте есть
std::start_lifetime_as, на практике ее нет.
Ну и что мне с этим делать? Писать какие-то свои заглушки, который будут затем развернуты в актуальный вызовstd::start_lifetime_asкогда он появится.А так нет
start_lifetime_asв большой тройке, и в стандарте ее нет.
ZirakZigil
26.11.2025 07:21А я и не предлагаю решать эту проблему
Т.е. вы предлагаете просто позаниматься канцелярскими делами. Зачем на это тратить время, правда, не очень понятно.
Чуть меньше чем все, наверное.
Ничего. В обоих случаях я не могу использовать
start_lifetime_as. А когда она появится, то в обоих случаях я смогу её использовать в один момент времени.
eao197
26.11.2025 07:21Т.е. вы предлагаете просто позаниматься канцелярскими делами.
Во-первых, я ничего не предлагаю. Всего лишь интересуюсь рассматривают ли в комитете сложившуюся ситуацию как проблему или нет.
Во-вторых, не понимаю, откуда вы сделали такой вывод. Сейчас судьба пропозала такова: пропозал вносится, над ним работают, затем его признают готовым к включению, после чего он входит в стандарт и, если нужно, далее вносятся правки.
Можно сделать так, что когда пропозал объявляют готовым к принятию в стандарт, то он не вносится в стандарт сразу. А дожидается пока его реализуют. Только после этого его текст вновится в стандарт.
Дополнительный плюс здесь в том, что если в процессе реализации обнаруживаются подводные камни (вот как в случае с trivial relocatable), то не нужно ничего из стандарта отзывать или вносить в стандарт корректирующие правки.
В обоих случаях я не могу использовать start_lifetime_as
Тогда у меня нет ответа на вопрос: зачем иметь в стандарте C++23 фичу, которой нельзя пользоваться на практике в конце 2025-го года?
Меня лично, за 30 лет с C++, эта ситуация очень забодала. Не так конечно, как необходимость использовать CMake, но все-таки. В 1990-е еще было понятно ради чего ждать, типа первый стандарт, в мире C++ ничего подобного еще не было. Но с момента принятия первого стандарта уже 27 лет прошло. А мы как будто бы ничему не учимся.

ZirakZigil
26.11.2025 07:21зачем иметь в стандарте C++23 фичу, которой нельзя пользоваться на практике в конце 2025-го года?
Вам от этого ни тепло, ни холодно, зачем этим вопросом вообще задаваться? Если фичу обозначили как "надо" в N году, а сделали в N+3, то вы сможете ей пользоваться только в N+3 году, независимо от того, внесли ли её в стандарт в году N, или в году N+3.

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 код пишу, то почему не имею возможности использовать то, что в стандарте описано?
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
Ваши действия — ваша ответственность, не нужно её перекладывать на комитет или вендора.

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, насколько мне известно.Вопрос: как мне быть в этой ситуации?

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))));

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]], которые так просто не объедешь.

antoshkka Автор
26.11.2025 07:21После чего вот прям благодать настала со стандартами C++14 и C++17. Но вот уже с C++20 опять та же
С C++20 основная засада - модули. Остальное всё уже реализовано, но модули - очень большая и многогранная фича, требующая работы над множеством частей C++ (форнтенд и мидленд компилятора, линкеры, системы сборки, библиотеки, ...)
В С++23 и C++26 нет таких "монстров", так что должно всё гладко идти и вендоры быстро наверстают отставание

rsashka
26.11.2025 07:21С C++20 основная засада - модули
Если я правильно запомнил тезисы твоего выступления на C++ Zero Cost Conf про модули ,то там основная засада, это макросы препроцессора.
Хотелось бы услышать твое мнение насчет этого предложения, которое должно решать проблемы модулей с макросами и сохраняет обратную совместимость со старым кодом.

antoshkka Автор
26.11.2025 07:21Международный комитет выступил против подобной идеи https://github.com/cplusplus/papers/issues/2316
Если хочется продолжить работу - нужна новая, более внушительная, мотивация

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

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 и комитет был против

rsashka
26.11.2025 07:21Данный пример не принципиальный и не является ключевым. Ведь новое поведение может быть каким угодно, и раз модуль "уже "запечён", и в него ничего больше не прилетает. ", тогда пусть локальные макросы модуля будут доступны только внутри компилируемого модуля, а в импортируемых модулях недоступны.
Поправил описание предложения
Что-то схожее предлагалось в https://github.com/cplusplus/papers/issues/2316 и комитет был против
Это совершенно другое предложение, которое наоборот запрещает экспорт макросов из модулей и добавляет обработку имен макросов в С++ модулях на уровне AST, а не только во время работы препроцесоора.

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

rsashka
26.11.2025 07:21В данном случае никакой новый функционал не добавляется и основная задача предложения - это не сломать старое поведение мароксов в легаси коде (с их обработкой только в препроцессоре)
Но так как макросы действительно ломают логику в С++ модулях, то формально макросы остаются, (чтобы не получить негатив от приверженцев старого С++), но их поведение в модулях меняется, так как добавляется дополнительный анализ на уровне AST. Фактически это плавный переход от макросов препроцессора к будущей рефлексии, т.к. с помощью последней можно сделать примерно тоже самое.
но слишком много нюансов и проблем возникает, пока кажется что овчинка не стоит выделки
Я могу сделать пример реализации этой фичи с помощью clang плагина, чтобы была возможность проверить предложенное поведение на реальном коде, но вряд ли смогу понять её применимость для С++ модулей, так как не знаю всех их тонкостей и нюансов.

antoshkka Автор
26.11.2025 07:21В данном случае никакой новый функционал не добавляется и основная задача предложения - это не сломать старое поведение мароксов в легаси коде (с их обработкой только в препроцессоре)
Но ведь макросы и так можно использовать в именованных модулях в global module fragment и они прорастают ниже в module unit, и за его пределы не экспортируются.
Так зачем делать работу, по обучению AST в макросы?

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

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

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

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

rsashka
26.11.2025 07:21Но ведь именно эту проблему ты и озвучивал в своем докладе (потенциальная зависимость интерфейса модуля от макросов времени компиляции), но если этой проблемы не существует, тогда мое предложение действительно не имеет смысла.
Если же такая проблема все же присутствует, тогда её можно решить добавлением анализа имен макросов после построения AST, но вот в каких местах это нужно делать, я со 100% точностью сказать не смогу.
Если ты считаешь, что раскрытие макросов в
namespaceдопускаются, пусть будет так. Как я уже сказал, я не знаю всех тонкостей использования модулей и не вижу смысла спросить со специалистом.

LinkToOS
26.11.2025 07:21встречи ISO C++ на Гавайях
Как там погода, на Гавайах?
Почему статья без фотографий? Стоило ли собираться на Гавайях, если нет классных фоток?
Какой вообще смысл в таких тусовках? Что там происходит такого, чего нельзя решить с помощью телеконференций и дистанционного голосования?
antoshkka Автор
26.11.2025 07:21Как там погода, на Гавайах?
Не в курсе, я удалённо участвовал :)
Но не удивлюсь, если офлайн участники тоже не знают какая там погода - обычно времени на осмотр окресностей нет, график очень плотный, а в больших аудиториях с окнами зачастую напряжёнка
Какой вообще смысл в таких тусовках?
Основной смысл - общий сбор, точка синхронизации и формального голосования. Онлайн тоже есть, но встреча работает эффективнее

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

domix32
26.11.2025 07:21В частности, на этом заседании не дошли руки до P3725, который делает надёжный и безопасный
std::ranges::filter, не подверженный проездам по памяти и Segmentation Fault в примерах наподобие:господи, да что не так с этим языком. почему нельзя было сделать, чтобы всё работало нормально изначально. сколько те рэнжи пилили, а косая кривулина всё равно оказалась в стандартной библиотеке да ещё и в одной из самых востребованных частей и теперь изобретают другую такую же штуку, но другую, которая будет подтирать кособокость первой.
Отдельно вопрос - а не думал ли кто-нибудь сделать альтернативные API на опционалах по аналогии ржавых?

antoshkka Автор
26.11.2025 07:21альтернативные API на опционалах
Вроде бы уже всё есть. Можете пожалуйста привести пару примеров, чего не хватает?

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 и прочие.

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

domix32
26.11.2025 07:21По аналогии с ржавым. А обновление делать через какой-нибудь
insert_or_update(). Собственно. поэтому вопрос про альтернативные API, типа как flux сделал, оставив некоторый слой совместимости с UB из std, ибо воткнуть их в текущую реализацию без горожения ещё большего ахтунга кажется нереально.
KanuTaH
26.11.2025 07:21Сейчас очень частая задача вида "если элемента с таким-то ключом еще нет в мапе, то вставить начальное значение, если он есть - то инкрементировать его на N" благодаря текущему API решается за один лукап. Продемонстрируйте, пожалуйста, как такая задача будет решаться за один лукап "по аналогии со ржавым" или "через какой-нибудь
insert_or_update()", а то лично мне например непонятно, в чем состоит идея и как эта идея что-то реально улучшит, за исключением "перехода на опционалы ради перехода на опционалы".
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 уровней выше по стеку со всеми проблемами разворачивания стека.

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++.
domix32
26.11.2025 07:21The 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.

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пожирает всю мапу до конца своего лайфтайма, тоже мягко говоря, не очень удобно.
domix32
26.11.2025 07:21Так вы сравниваете производительность разных имплементаций. Стандартный контейнер раньше при коллизиях вырождался в список со длинющим линейным лукапо со всеми вытекающими. Ситуацию вроде несколько улучшили, но всё равно просадка на коллизиях имеет место быть и тут не сильно принципиально, что он единственный. Гугловая табличка из abseil должна делать примерно то же самое, что и ржавая и оба делают SIMD-оптимизации лукапов, так что оно даже если с двойным лукапом должно получится быстрее чем стандартный лукап в std::umap/std::uset. Ну, а считать производительность на вырожденных случаях в дебаге несколько странное занятие.

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

Kelbon
26.11.2025 07:21это апи в крабовый язык добавлено исключительно потому что по другому невыразимо в так называемом safe подмножестве. То есть другими словами это костыль с оверхедом и абсолютно нечитаемый.
И вы предлагаете костыль перетащить в язык, где всё сделано логично и правильно

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

feelamee
26.11.2025 07:21То есть другими словами это костыль с оверхедом и абсолютно нечитаемый.
добавлю что эти коллбэки ещё и значительно усложняют дебаггинг

NN1
26.11.2025 07:21Откройте std::ranges алгоритмы.
Как раз то, что просили без итераторов
https://en.cppreference.com/w/cpp/algorithm/ranges/find.html

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 от объекта, так и от итератора - тут уж не знаю как правильнее. Но это позволит не писать название вектора три! раза, чтобы выполнить самую базовую операцию.

NN1
26.11.2025 07:21А если возвращать итераторы то можно просто использовать их сразу в алгоритме.
erase(find(c ,p), c.end())
Как вариант можно было сразу работать везде с отрезками как в D:

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

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

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

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

habr_skatilsa
26.11.2025 07:21какой шанс увидеть в C++ properties как в C#?

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

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

eao197
26.11.2025 07:21Я к тому, что properties -- это одна из самых спорных штук из тех, что хотелок, которые люди высказывали. На моей памяти любители properties говорят об этом с середины 1990-х, более того, ЕМНИП, Borland и Microsoft добавляли их поддержку в свои С++компиляторы в то время в виде нестандартных расширений языка.
Прошло 30 лет, никто от отсутствия properties не умер. А кто-то (вроде меня) и вообще не хотел бы их в языке видеть. Так что вероятность их добавления, имхо, крайне низкая.
Зато через рефлексию все любители этих самых properties смогут обеспечить себе свое личное щасте с большой буквы "Ща" ;)

habr_skatilsa
26.11.2025 07:21кто их не хочет видеть, может их не использовать

eao197
26.11.2025 07:21Но зачем усложнять работу компиляторостроителям ради фичи, которую не будут использовать, скажем, 90% пользователей языка?
У Страуструпа несколько лет назад было хорошее послание к комитету под названием "Вспомните Vasa": https://www.stroustrup.com/P0977-remember-the-vasa.pdf

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

eao197
26.11.2025 07:21Откуда вообще такая статистика? 90%, а может 89%?
Это не статистика, вы не обратили внимания на слово "скажем" в моем предложении.
Но если вы хотите убедить комитет в важности такой фичи, как properties, то вы можете как-то собирать такую статистику и продемонстрировать.
Так же после появления рефлексии вы можете написать прототип и на реальных примерах показать как хорошо решаются те или иные проблемы.
Кто-то помер там от отсутствия фич языка, а кто-то не помер?
Сам факт того, что за последние 30 лет огромное количество софта было написано на C++ без properties доказывает, что это не критичная штука.
При этом те же самые 30 лет показывают, что по каким-то темам накапливается критическая масса пожеланий для внедрения новых фич (variadic templates, lambdas, if constexpr, concepts, compile-time reflection, ...). Т.е. по этим направлением выгода от новых фич достаточно очевидна.
По поводу properties большие сомнения. Но вы можете их попробовать развееть.
Может попытаемся вести адекватный диалог?
Да я как бы уже. Но адекватные не означает, что здесь будут озвучиваться вещи которые удовлетворят вас.

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

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

eao197
26.11.2025 07:21Любезный, я практически никогда не ставлю минусы на Хабре. За все время присутствия здесь минусов от меня для статей/комментариев наберется всего с десяток. А минусов в карму не было вообще никогда.
В этом обсуждении я ни одного минуса никому не поставил.
Но пруфов не будет, придется поверить на слово.
eao197
Антон, а поднимается ли в комитете вопрос изменения периодичности выхода стандартов С++?
Например, выпускать их не раз в три года, а раз в два года, раз в год или даже два раза в год?
Сейчас получается следующая ситуация: есть некий жесткий дедлайн, ибо если что-то не входит в C++26, то затем придется ждать целых три года. Как раз пример с trivial relocation. В C++26 не попадает, но, возможно, уже в следующем году это предложение будет доработано, ему придется ждать до C++29.
А вот если бы стандарт выходил раз в год, то окончательный trivial relocation мог бы войти в C++27.
Как я понимаю, комитет сейчас работает по "train model" (если не ошибся с названием): в работе постоянно находится N предложений. К некоторой отсечке времени (за полгода-год до финализации) в новый стандарт включаются те предложения, прогресс по котором признан достаточным. А остальные предложения продолжаются разрабатываться.
В этой модели, в теории, без разницы как часто делается отсечка по времени -- раз в три года или раз в два года. Или даже два раза в год.
antoshkka Автор
Выпуск стандарта ещё влечёт за собой накладные расходы - формальное создание особого черновика, сбор коментариев от стран, испраление замечаний, финализация стандарта в вышестоящих инстанциях ISO... Это достаточто ресурсоёмкие процессы
Пока кажется что 3 года - отличный баланс между скоростью выпуска новых фичей и уменьшением мороки для людей в комитете
eao197
А разве нет возможности это распараллелить? Т.е. вот произошла отсечка времени, например, летом 2025-го. Некая группа далее занимается обслуживанием бюрократии для оформления текста стандарта. А остальные возобновляют работы над текущими предложениями.
А тут неизбежно возникает следующий вопрос: а так ли важна сейчас для C++ именно ISO стандартизация?
Ну т.е. роль ISO стандарта в начале 1990х была понятна.
Но сейчас-то зачем?
Допустим, будет условная некоммерческая организация C++ Foundation, которая раз в N месяцев выпускает некий свой документ под названием C++YY language specification. И все.
По факту же, всем компиляторостроителям абсолютно похер на содержимое стандарта: есть в стандарте фичи X1, X2, X3, X4 и X5, а мы сделаем поддержку только X1, X3 и X5. Остальные когда-нибудь, когда руки дойдут. Если дойдут.
И смысл наличия ISO-шного стандарта для непосвященных совершенно ускользает в современных реалиях.
antoshkka Автор
Оно уже распараллелено, насколько это возможно. Однако, есть критические секции, которые не паралеллятся или плохо паралеллятся
Как ни странно - да. C++ чуть ли не единственный современный язык программирования, который можно использовать в приложениях, напрямую влияющих на жизнь человека (самолёты, автомобили, медицинское оборудование, ...). А для такого использования нужна ISO стандартизация.
Без этого - потеряется ощутимая часть пользователей
eao197
Мне казалось, что у Ada там позиции гораздо крепче, чем у C++.
Ну и такими темпами скоро С++у только и останется, что цепляться за ниши, в которых есть формальное требование наличия ISO-стандарта.
Да и то до тех пор, пока каким-нибудь решением американского конгресса директивно запретят использовать Си и C++ под предлогом небезопасности. И начнут вместо применять условый Rust без оглядки на отсутствие ISO-стандарта для оного.
rsashka
Вы правы в том, что С++ есть чему получиться у Ada. Это касается требований к языку в части безопасной разработки перед началом его создания, которые отсутствовали у С и С++.
Jijiki
и потом разраб такой, по каким-либо причинам забивает на язык, и возвращается в язык спустя 3 года, и такой сидит и перед ним пролетают килотонны правил, ""так это можно, это нельзя, это было в легаси, так стоп это же теперь в самом новом стандарте" )
eao197
Типа сейчас очень просто взять и после C++14 переучиться на C++26. Ага.
Так-то наоборот, если принимать стандарт раз в год, то дельта изменений по сравнению с предыдущим будет меньше.
rsashka
Так вообще не нужно переучиваться, так как процесс стандартизации обеспечивает обратную совместимость и не требуется ничего переписывать, из-за того, что в новой версии сломали старое поведение компилятора или стандартной библлиотеки (как это бывает без стандартизации).
eao197
Во-первых, вы смело можете адресовать свои слова оратору выше. Это он чего-то опасается.
Во-вторых, как бы опыт С++11 говорит, что не так все однозначно.
А принятие модулей в стандарт C++20 -- это тоже отдельная песТня.
rsashka
Принятие стандарта не означает обязательность его использования.
eao197
Рано или позно все равно придется переходить.
rsashka
Нужно переходить не тогда, когда "можно", а тогда, когда без новых фич уже нельзя.
eao197
А могли бы вы мне рассказать, что именно вы пытаетесь до меня донести?
rsashka
Можно посмотреть в истории:
Что принятие стандарта не требует его немедленного изучения и обязательного применения.
eao197
Т.е. человек 10 лет сидел на C++14, потом пришло время перейти на C++26 и тут вдруг оказалось, что мои слова "Типа сейчас очень просто взять и после C++14 переучиться на C++26. Ага." не соответствуют действительности.
Так я и поверил, ага.
PS. Вы как-то по своему эту фразу восприняли, я не говорил о том, что стандарты нужно изучать по мере их публикации.
rsashka
Я написал про то, что использованное вами слово "переучиваться" и сам тон комментария намекает на обязательность переобучения на новый стандарт, тока как я пишу про то, что использование фич из новых стандартов опционально.
Более того, например, я точно уверен, что знаю далеко не все фичи и тонкости новых стандартов, но это не мешает мне писать под C++23.
eao197
Я говорю про свой опыт: мне пришлось переучиваться на C++11, т.к. те же лямбды и variadic templates позволили отказаться от старых приемов.
Затем пришлось переучиваться на C++17, т.к. там и structured binding, и if constexpr, и fold expressions.
Затем пришлось переучиваться на C++20, т.к. там и концепты и тот же operator<=> (с которым есть неочевидные моменты). Короутины еще. Модули.
В C++23 появился deducing this.
Так-то смысл перехода на новый стандарт именно в том, чтобы освоить новые трюки и научиться обходиться без старых.
Приедет C++26 и нужно будет учиться жить с рефлексией.
rsashka
Я с вами согласен, что использование новых стандартов обязательно требует из изучения :-)
KiddingBanana
А минорные фичи типа fold expression и deducing this точно требуют именно переучивания?
Имхо, большие изменения были в 11 стандарте, в чуть меньшей степени в 20 и теперь в 26
eao197
deducing this еще не пробовал. А вот по поводу fold expression у меня регулярно бывают моменты, когда глаза на лоб лезут видя как более опытные в современном C++ люди на fold expression делают то, что я бы делал на функциях с variadic-шаблонами и явной остановкой рекурсии.
Siemargl
А теперь возьмем обратный вариант - нужно портировать такое на платформу со старым компилятором. И тут упс, а более опытный в современном стандарте уже не помнит, как деды писали =)
Dooez
Не могу согласиться.
Чем дольше оттягивать переход, тем больше кода который не использует новые идиоматические подходы, и больше кода который потенциально будет мешать переходу (хотя это уже маловероятно если не отставать на 9 лет)
Переходить на новый стандарт нужно как можно скорее. Это не значит что нужно использовать вообще все его новшества, но наверное в каждом стандарте есть вещи которые упрощают жизнь и имеют крайне низкое трение даже со стороны консервативных коллег.
rsashka
Переход на новый стандарт не может быть самоцелью, и если приложение и так работает, то зачем его переписывать?
так я про это и написал, когда что-то улучшается, упрощается, повышается надежность и т.д.
Jijiki
но ведь нельзя писать на разных стандартах или можно? щас я наверно минус получу, тогда выходит, если обновилась библиотека "OpenSSL" - язык почти похож на коробку с библиотекой "почти" мне кажется, то на новую версию можно и не переходить, обновление языка, касается и безопасности в том числе, а не просто ради удобства что-то изменилось, поведение кодогенератора может отличаться, может быть улучшена поддержка чего-то, мне кажется новый стандарт как и новая версия или некая стабилити всегда свежесть и выйгрыш, да понимаю, есть килотонны кода, но я так попытался подумать в версии как смог
Gosling-Emacs вот например уже не собрать без знаний, "потомучто произошли изменения в кодинге" уже те какие всё как мне кажется уже фатальны на этапе сборки
maisvendoo
Хм, как частота выхода стандартов повлияет на их реализацию компиляторами? Не все фичи C++20 еще пришли в тот же mingw, например. Я не говорю уже про C++23, а на дворе уже 2025 заканчивается. По мне так наоборот - пореже бы их выпускали
NN1
В том и дело, что стандарт и реальность не просто различаются, а вообще разные миры.
У нас каждый конкретный компилятор в конкретной версии реализуют какую-то часть каких-то стандартов.
В итоге мы не можем просто взять и ориентироваться полностью на стандарт даже если этого хотим.
eao197
Никак.
Первая идея вот в чем. Cейчас есть два момента:
спешка перед заталкиванием предложения в стандарт перед дедлайном. Грубо говоря, какой-то пропозал почти готов, но если не принять его сейчас, то он войдет лишь в следующий стандарт через 3 года. Поэтому его могут принять даже не смотря на недоделки. Чтобы затем фиксить то, что недосмотрели;
долгая пауза между принятием в стандарт и выходом самого стандарта. Допустим, летом 26-го года какую-то фичу примут в С++29. Но формально она станет частью C++ только после принятия C++29. Т.е. в 2029-ом году.
Если выпускать стандарты раз в год, то тяжесть этих моментов практически нивелируется.
Вторая идея в том, что если комитет таки начнет синхронизировать то, что попадает в документ с тем, что есть в компиляторах, то частые выпусти релизов позволят чаще синхронизировать состояние компиляторов с текстом стандарта. Грубо говоря, сделают поддержку рефлексии в 3-х основных компиляторах в 2027-ом и тут же можно будет обновить C++27 или C++28. А не ждать принятия C++29.
Но в то, что комитет как-то начнет синхронизироваться с разработичками компиляторов я уже не верю. Люди нормально живут в своей парадигме, зачем что-то менять?
Zalechi
В целом поддерживаю ваш комментарий, хотел бы развить в контексте цитаты выше:
А что если отойти в сторону и воспринимать комитет, как политический орган. По сути ISO это прослойка между Государством (заказчиком) и бизнесом (потребителем). Тогда все встает га свои места:
Комитет — это международное техническое бюро по стандартизации технологий. Призван регламентировать с одной стороны, давать техническое обеспечение с другой.
Обожаю пример с ПДД. Мы вынуждены регулировать движение транспортных средств по дорогам общего пользования. Как итог, бизнес производит относительно безопасное современное движение транспортных средств по тем самым дорогам общего пользования.
Все эти правовые, научно-прдпринимательские отношения решаются в таком порядке. Поэтому лаг.
но не мне решать, даст ли предложение о выпуске стандарта каждый год, ускорение имплементации клнечных решений в бизнес конвееры (в поле).
… или как это работает?
eao197
Интересная аналогия, спасибо.
Но, имхо, сравнивать лучше не с ПДД. ПДД -- это ближе к каким-нибудь стандартам MISRA.
А вот ISO-шный стандарт для C++ больше похож на ГОСТы для строительных материалов: типа плиточный клей такой-то, пеноблок такой-то, плита перекрытия такая-то. Т.е., согласованные экспертами спецификации, а уже конкретная продукция, удовлетворяющая этим спецификациям, производится разными заводами стройматериалов.
Только вот получается, что если тебе нужно построить дом, то ориентироваться приходится не на то, что есть в принципе, а лишь на то, что доступно в ближайшем магазине стройматериалов. И если туда чего-то не завезли, то не судьба -- спецификация живет отдельной жизнью, ассортимент в магазине -- своей :(
Zalechi
Тоже не плохой пример, но и комитет не всесильный орган, а лишь техническая экспертная группа.
А вот кто в правительстве следить за соответсвие продукции стандартам — могу только догадываться.
eao197
Вот поэтому-то и есть идея о том, что комитет вводит дополнительный статус для предложений: готово к включению в стандарт, но еще не реализовано. И такие фичи в текст стандарта не включаются до тех пор, пока не перейдут в статус "готово к включению в стандарт, реализовано".
Т.о. компенсируется та проблема, что комитет не может повлиять на скорость реализации конкретной фичи в компиляторах. Но зато может формировать стандарт только из тех фич, которые уже реализованы в основных компиляторах.
От того, что какая-то фича будет ждать своей реализации годами нас это не спасет. Но зато мы точно будем понимать, что если есть условный С++32, то он практически весь реализован в свежих версиях компиляторов. А не как сейчас.
Ну и при таком раскладе публикация стандарта раз в год приобретает большой смысл, т.к. если какая-то фича оказалась реализована в большой тройке, то нет смысла ждать больше года, чтобы она стала частью официального стандарта.
Zalechi
понял.
Siemargl
А это было раньше - я помню TR1, и вроде как позже зафиксировали подобный путь развития.
vanxant
Да вот как раз слона проще есть по частям. Всем будет понятнее "естественный" порядок имплементации фич, типа сначала сделайте 26, а потом уже 27 (который частично зависит от 26).