Re[9]: Полухин - что там с С++26
От: Олег К.  
Дата: 19.12.25 10:53
Оценка:
ОК>>Это и был аргумент. Если ты не понимаешь, то и C++ и сама разработка софта ушли совсем не в том направлении.

N>Лямбды, вывод типов — это всё пришло из других языков. Новый (относительно новый) синтаксис цикла — это вообще точь-в-точь, как в Питоне. Смогли же! Удачно? Да, вполне. Или ты в принципе только за канонический С++, который без шаблонов и stl? Давай уже полный список.


Какие-то фичи удачные, а какие-то нет. Питоновские f-strings не нужны в плюсах. И я за stl и разумное и уместное использование шаблонов.
Re[11]: Полухин - что там с С++26
От: so5team https://stiffstream.com
Дата: 19.12.25 11:19
Оценка:
Здравствуйте, Олег К., Вы писали:

ОК>И C++ и современная разработка софта переусложнены.


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

ОК>Я знаю, что ты знаешь последний стандарт плюсов


Как раз не знаю.

ОК>но разработка софта это не про запихивание последних фич стандарта в код.


Это да.

ОК>Как пример, сравни дизайн своего кода ниже с аналогичным кодом из .NET. В .NET-е и дизайн более высокоуровневый и клиентский код чище.


Не вижу смысла. В .NET-е есть свои возможности, под .NET следовало бы писать в стиле .NET.

В C++ есть свои возможности (и нет многого, что есть в .NET). Мы делали свой дизайн под a) возможности тогдашнего C++ (это был C++14) и b) под свои представления о прекрасном.

ОК>Вообще просто сравни свой стиль программирования со стилем из QT, например.


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

Но если смотреть примеры из Qt, то там, в принципе, ведь почти тоже самое:
    QHttpServer httpServer;
    httpServer.route("/", []() {
        return "Hello world";
    });

    httpServer.route("/query", [] (const QHttpServerRequest &request) {
        return host(request) + u"/query/"_s;
    });

    httpServer.route("/query/", [] (qint32 id, const QHttpServerRequest &request) {
        return u"%1/query/%2"_s.arg(host(request)).arg(id);
    });

    httpServer.route("/query/<arg>/log", [] (qint32 id, const QHttpServerRequest &request) {
        return u"%1/query/%2/log"_s.arg(host(request)).arg(id);
    });

    httpServer.route("/query/<arg>/log/", [] (qint32 id, float threshold,
                                              const QHttpServerRequest &request) {
        return u"%1/query/%2/log/%3"_s.arg(host(request)).arg(id).arg(threshold);
    });

    httpServer.route("/user/", [] (const qint32 id) {
        return u"User "_s + QString::number(id);
    });
    ...

Только еще и с дополнительными телодвижениями со стороны пользователя:
    auto tcpserver = std::make_unique<QTcpServer>();
    if (!tcpserver->listen() || !httpServer.bind(tcpserver.get())) {
        qWarning() << QCoreApplication::translate("QHttpServerExample",
                                                  "Server failed to listen on a port.");
        return -1;
    }
    quint16 port = tcpserver->serverPort();
    tcpserver.release();


Не вижу принципиальных различий с чем-то вот таким:
    // GET request to homepage.
    router->http_get( "/", []( auto req, auto ){
        return
            init_resp( req->create_response() )
                .set_body( "GET request to the homepage.")
                .done();
    } );

    // POST request to homepage.
    router->http_post( "/", []( auto req, auto ){
        return
            init_resp( req->create_response() )
                .set_body( "POST request to the homepage.\nbody: " + req->body() )
                .done();
    } );

    // GET request with single parameter.
    router->http_get( "/single/:param", []( auto req, auto params ){
        return
            init_resp( req->create_response() )
                .set_body(
                    fmt::format(
                        RESTINIO_FMT_FORMAT_STRING(
                            "GET request with single parameter: '{}'" ),
                        restinio::fmtlib_tools::streamed( params[ "param" ] ) ) )
                .done();
    } );


ОК>Только не надо говорить, что на современном C++ так не пишут.


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

S>>Upd. Нашлось вот это: https://www.govnokod.ru/23374

S>>Но пример взят не с сайта, а из комментария на Хабре, да еще и с измененным пространством имен.

ОК>Этот пример на сайте и был. Вроде внизу были у вас несколько примеров кода для разных библиотек. Посмотри в своей системе контроля версий.


У нас в системе контроля версий сохранилась информация только с 2018-го года. И ничего подобного не видно. Скорее всего подобные сравнения были не на сайте, а в каких-то публикациях. Помнится, мы даже отдельно делали сравнение с тогдашней версией Beast-а.

Посредством web.archive тоже ничего подобного не находится.
Re[3]: Полухин - что там с С++26
От: B0FEE664  
Дата: 19.12.25 18:08
Оценка: +1
Здравствуйте, Великий Мессия, Вы писали:

ВМ>о том что бы аргументы писать в строке форматирования

ВМ>как в расте и питоне
ВМ>что бы в C++ можно было сделать так же

ВМ>

ВМ>int var = 4;
ВМ>std::print("a = {var}");
ВМ>std::string str = std::format("a = {var}");


А зачем?
Чем это лучше:
std::string str = "a = " + std::to_string(var);


И вообще, зачем формат, если это потоковый вывод?

Вместо вот этого:
void display(std::string_view prefix, int bits) {
std::print(f"{prefix}-{errno}: got {calculate(bits)} for {bits:#06x}");
}

органично выглядит вот так:
out::display() << prefix << errno << ": got " << calculate(bits) << " for " << hex(6) << bits << out::endl;


Я ещё могу понять, что некоторым не нравятся "шевроны", но тогда было бы логично предложить какой-нибудь приличный синтаксис для потока, а не вот это вот всё с закрывающими и открывающими скобками.
И каждый день — без права на ошибку...
Re[4]: Полухин - что там с С++26
От: Великий Мессия google
Дата: 19.12.25 18:36
Оценка: +2
Здравствуйте, B0FEE664, Вы писали:

BFE>И вообще, зачем формат, если это потоковый вывод?


если потоковый вывод подразумевается iostream
то он по скорости давно уже позади того же fmt/std::format
бенчмарки погугли

BFE>Вместо вот этого:

BFE>
BFE>void display(std::string_view prefix, int bits) {
BFE>std::print(f"{prefix}-{errno}: got {calculate(bits)} for {bits:#06x}");
BFE>}
BFE>

BFE>органично выглядит вот так:

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

BFE>
BFE>out::display() << prefix << errno << ": got " << calculate(bits) << " for " << hex(6) << bits << out::endl; 
BFE>


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


вот и используй fmt/std::format
Re[5]: Полухин - что там с С++26
От: B0FEE664  
Дата: 19.12.25 19:42
Оценка:
Здравствуйте, Великий Мессия, Вы писали:

BFE>>И вообще, зачем формат, если это потоковый вывод?


ВМ>если потоковый вывод подразумевается iostream

ВМ>то он по скорости давно уже позади того же fmt/std::format
ВМ>бенчмарки погугли
Почему именно iostream ? Можно написать намного быстрее.

ВМ>во первых как сказал выше, это тормозно

Вот как написали, так оно и будет.

ВМ>во вторых, глазами теряется общий формат строки, иногда и часто это важно

Это вообще не аргумент. Вот в этой строке "{prefix}-{errno}: got {calculate(bits)} for {bits:#06x}" вообще всё потеряно. И это ещё инициализации , типа int{} туда не засунули.
Я понял бы аргумент про перевод на другой язык, где местами надо менять аргументы вывода, но не этот.

BFE>>
BFE>>out::display() << prefix << errno << ": got " << calculate(bits) << " for " << hex(6) << bits << out::endl; 
BFE>>


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

ВМ>вот и используй fmt/std::format
Я его и использую, для форматированного вывода. А для потокового использую потоки.
И каждый день — без права на ошибку...
Re[6]: Полухин - что там с С++26
От: Великий Мессия google
Дата: 19.12.25 21:43
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Здравствуйте, Великий Мессия, Вы писали:


BFE>>>И вообще, зачем формат, если это потоковый вывод?


ВМ>>если потоковый вывод подразумевается iostream

ВМ>>то он по скорости давно уже позади того же fmt/std::format
ВМ>>бенчмарки погугли
BFE>Почему именно iostream ? Можно написать намного быстрее.

потому что мы рассматриваем стандартные способы вывода/форматирования

все что там кто то себе лично написал, не интересно
один уже написал — fmt, теперь это повсеместно и в стандарте std::format
и по скорости пока никто ничего лучшего не предложил

ВМ>>во первых как сказал выше, это тормозно

BFE>Вот как написали, так оно и будет.

ась?

ВМ>>во вторых, глазами теряется общий формат строки, иногда и часто это важно

BFE>Это вообще не аргумент. Вот в этой строке "{prefix}-{errno}: got {calculate(bits)} for {bits:#06x}" вообще всё потеряно. И это ещё инициализации , типа int{} туда не засунули.
BFE>Я понял бы аргумент про перевод на другой язык, где местами надо менять аргументы вывода, но не этот.

смотря кому и кто с чем работает
не беря твой любимый потоковый << вывод
любые sprintf/fmt/std::format где внутри длинная строка(а это ускоряет если не склеивать потом эти строки)
то можно спутать аргументы и потерять всякие переводы строк итд


BFE>>>
BFE>>>out::display() << prefix << errno << ": got " << calculate(bits) << " for " << hex(6) << bits << out::endl; 
BFE>>>


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

ВМ>>вот и используй fmt/std::format
BFE>Я его и использую, для форматированного вывода. А для потокового использую потоки.

чудесно, для потокового вывода, когда и где скорость не важна, отличный выбор
но мы говорим о другом случае
Re[4]: Полухин - что там с С++26
От: Hоmunculus  
Дата: 20.12.25 00:21
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>А зачем?

BFE>Чем это лучше:

Тем что форматипованную строку можно целиком сохранить, например для переводчиков, и потом целиком же единую строку и выводить, а не разбивать на кучу подстрок
Re[4]: Полухин - что там с С++26
От: Went  
Дата: 21.12.25 17:13
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>А зачем?

BFE>Чем это лучше:
BFE>
BFE>std::string str = "a = " + std::to_string(var);
BFE>

Медленно и многословно.

BFE>И вообще, зачем формат, если это потоковый вывод?

Потоковый вывод и интерполяция строк это теплое и мягкое. Суть интерполяции это компактное по записи и оптимальное по скорости построение цельной строки, а не последовательное сохранение чего куда-то.

Другое дело, что я не уверен, что в С++ это нужно, тем более на уровне ядра языка. В C# философия одна, там очень ценны разные инструменты быстрого написания прикладного кода, в С++ же, если код пестрит такими вот "интерполяциями", то, скорее, что-то не то с архитектурой.
Re[5]: Полухин - что там с С++26
От: B0FEE664  
Дата: 05.01.26 09:38
Оценка: +2
Здравствуйте, Hоmunculus, Вы писали:

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


Сохранять "форматипованную" (что бы это не значило) строку содержащую имена локальных и глобальных переменных — так себе идея. Переименование переменной, изменение зоны видимости, добавление локальной переменной перекрывающую переменную в строке => проблема.
И каждый день — без права на ошибку...
Re[5]: Полухин - что там с С++26
От: B0FEE664  
Дата: 05.01.26 09:42
Оценка:
Здравствуйте, Went, Вы писали:

BFE>>А зачем?

BFE>>Чем это лучше:
BFE>>
BFE>>std::string str = "a = " + std::to_string(var);
BFE>>

W>Медленно и многословно.
Точно медленно?

А многословно — чем плохо? Читать же легче.

BFE>>И вообще, зачем формат, если это потоковый вывод?

W>Потоковый вывод и интерполяция строк это теплое и мягкое. Суть интерполяции это компактное по записи и оптимальное по скорости построение цельной строки, а не последовательное сохранение чего куда-то.
Не понял, почему "оптимальное по скорости построение цельной строки"? Откуда это следует?
А то, что компактное — это не всегда хорошо.
И каждый день — без права на ошибку...
Re[7]: Полухин - что там с С++26
От: B0FEE664  
Дата: 05.01.26 09:52
Оценка:
Здравствуйте, Великий Мессия, Вы писали:

ВМ>смотря кому и кто с чем работает

ВМ>не беря твой любимый потоковый << вывод
ВМ>любые sprintf/fmt/std::format где внутри длинная строка(а это ускоряет если не склеивать потом эти строки)
В потоках вообще нет операции выделения динамической памяти и склеивать строки не надо. Так за счёт чего потоковый вывод (если он написан оптимально) возможно обогнать?

ВМ>то можно спутать аргументы и потерять всякие переводы строк итд

Спутать аргументы и потерять всякие переводы строк для форматированной строки так же легко, как и для потока.
И каждый день — без права на ошибку...
Re: Полухин - что там с С++26
От: B0FEE664  
Дата: 05.01.26 10:57
Оценка:
Здравствуйте, Великий Мессия, Вы писали:

ВМ>ответ Антона — что то типа, разработчики компиляторов протестуют/бунтуют, короче не хотят, для них это якобы сложно


Посмотрел, наконец, видео и понял, что разработчики компиляторов правы.
Правильно говорят, что с подобной строкой будут схожие проблемы, что и с std::initializer_list.

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

Я так понимаю, что при наличии рефлексии обеспечить, например, для строки
"a = {var}"_F

вызов
std::format("a = {}", var)

должно быть не очень сложно, даже при отсутствии списка локальных переменных. Но для этого надо иметь возможность протащить захват локальных переменных в literal operator...
И каждый день — без права на ошибку...
Re[5]: Полухин - что там с С++26
От: sergii.p  
Дата: 05.01.26 11:14
Оценка: 3 (1)
Здравствуйте, Went, Вы писали:

BFE>>Чем это лучше:

BFE>>
BFE>>std::string str = "a = " + std::to_string(var);
BFE>>

W>Медленно и многословно.

как раз быстро https://quick-bench.com/q/AHUvx7pCnwWGf1b7esOLgCB4G7s
Для таких простейших случаев простая конкатенация проще и быстрее.
Re: Полухин - что там с С++26
От: Aquilaware  
Дата: 05.01.26 15:41
Оценка: +2
Здравствуйте, Великий Мессия, Вы писали:

ВМ>форматирование аргументов в С++26 как это сделано в расте или питоне


По-правильному это называется интерполяцией строк, а не форматированием аргументов.
Re[6]: Полухин - что там с С++26
От: Went  
Дата: 07.01.26 18:29
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>>>Чем это лучше:

BFE>>>
BFE>>>std::string str = "a = " + std::to_string(var);
BFE>>>

W>>Медленно и многословно.
BFE>Точно медленно?
Ну, в приведенном выше случае разница сомнительна, но если мы подставляем несколько объектов в некоторый текст, то при конкатенации многократного копирования не избежать. А умная, оптимизированная интерполяция может предугадать необходимый размер (или использовать один заготовленный большой временный буфер), и лишнего копирования избежать. Или я ошибаюсь?

BFE>А многословно — чем плохо? Читать же легче.

Мне легче прочитать:
auto str = $"a = {var}";


BFE>Не понял, почему "оптимальное по скорости построение цельной строки"? Откуда это следует?

См. выше.
BFE>А то, что компактное — это не всегда хорошо.
В прикладном коде — хорошо. У меня, например, проект — по сути гигантский кодогенератор на C#. Там интерполяция, как говорится, "что доктор прописал".
Re[6]: Полухин - что там с С++26
От: Went  
Дата: 07.01.26 18:30
Оценка:
Здравствуйте, sergii.p, Вы писали:

SP>как раз быстро https://quick-bench.com/q/AHUvx7pCnwWGf1b7esOLgCB4G7s

SP>Для таких простейших случаев простая конкатенация проще и быстрее.
Я думал, мы обсуждаем общий случай, когда у нас 2,3 и более плейсхолдеров.
Re[7]: Полухин - что там с С++26
От: sergii.p  
Дата: 08.01.26 09:12
Оценка:
Здравствуйте, Went, Вы писали:

W>Я думал, мы обсуждаем общий случай, когда у нас 2,3 и более плейсхолдеров.


да хоть 100: https://quick-bench.com/q/JaEBjML9kSASLuGYUst4IS6xSAQ

Вот для float to_string деградирует сильно. Но часто ли надо рациональные выводить? Я в основном встречаю именно случай "blablabla {int}".
Re[8]: Полухин - что там с С++26
От: Went  
Дата: 09.01.26 18:11
Оценка:
Здравствуйте, sergii.p, Вы писали:

SP>да хоть 100: https://quick-bench.com/q/JaEBjML9kSASLuGYUst4IS6xSAQ

Немного не понимаю, что мы сравниваем? Конкатенацию с сохранением в поток и с std::format? А где здесь интерполяция?
Re[9]: Полухин - что там с С++26
От: sergii.p  
Дата: 10.01.26 11:44
Оценка:
Здравствуйте, Went, Вы писали:

W>Немного не понимаю, что мы сравниваем? Конкатенацию с сохранением в поток и с std::format? А где здесь интерполяция?


зачем переспрашивать, когда вы сами прекрасно отвечаете? Особенно последний вопрос относительно С++. Так и хочется ответить в рифму
Краткое содержание предыдущих частей. Здесь говорили про std::format, потоковый вывод и простую конкатенацию. Вы сказали, что "a = " + std::to_string(i) медленно, но как мы видим это не так. Даже если увеличить количество плейсхолдеров, и ожидать что за счёт перевыделения памяти мы получим экономию, мы видим, что выигрыш тоже сомнителен.
И что вы понимаете под интерполяцией? Это же обычный синтаксический сахар. Самое простое — реализовать его поверх std::format. Вот мы это и сравниваем. Как видно, он за счёт разбора строки проигрывает тривиальным вариантам. Если перенести всю эту головную боль на разработчиков компилятора, они не решат её лучше. Намного проще format оптимизировать.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.