ОК>>Это и был аргумент. Если ты не понимаешь, то и C++ и сама разработка софта ушли совсем не в том направлении.
N>Лямбды, вывод типов — это всё пришло из других языков. Новый (относительно новый) синтаксис цикла — это вообще точь-в-точь, как в Питоне. Смогли же! Удачно? Да, вполне. Или ты в принципе только за канонический С++, который без шаблонов и stl? Давай уже полный список.
Какие-то фичи удачные, а какие-то нет. Питоновские f-strings не нужны в плюсах. И я за stl и разумное и уместное использование шаблонов.
Здравствуйте, Олег К., Вы писали:
ОК>И C++ и современная разработка софта переусложнены.
Принципиально повлиять на это я не могу. Так что из этого тезиса сделать какие-то полезные выводы не представляется возможным.
ОК>Я знаю, что ты знаешь последний стандарт плюсов
Как раз не знаю.
ОК>но разработка софта это не про запихивание последних фич стандарта в код.
Это да.
ОК>Как пример, сравни дизайн своего кода ниже с аналогичным кодом из .NET. В .NET-е и дизайн более высокоуровневый и клиентский код чище.
Не вижу смысла. В .NET-е есть свои возможности, под .NET следовало бы писать в стиле .NET.
В C++ есть свои возможности (и нет многого, что есть в .NET). Мы делали свой дизайн под a) возможности тогдашнего C++ (это был C++14) и b) под свои представления о прекрасном.
ОК>Вообще просто сравни свой стиль программирования со стилем из QT, например.
В Qt свой стиль, который отлично подходит под некоторые типы GUI-приложений.
Однако применительно к другим вещам, типа работы с сетью, могут возникать вопросы.
Но если смотреть примеры из Qt, то там, в принципе, ведь почти тоже самое:
Только еще и с дополнительными телодвижениями со стороны пользователя:
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 тоже ничего подобного не находится.
Здравствуйте, Великий Мессия, Вы писали:
ВМ>о том что бы аргументы писать в строке форматирования ВМ>как в расте и питоне ВМ>что бы в C++ можно было сделать так же
ВМ>
Я ещё могу понять, что некоторым не нравятся "шевроны", но тогда было бы логично предложить какой-нибудь приличный синтаксис для потока, а не вот это вот всё с закрывающими и открывающими скобками.
BFE>Я ещё могу понять, что некоторым не нравятся "шевроны", но тогда было бы логично предложить какой-нибудь приличный синтаксис для потока, а не вот это вот всё с закрывающими и открывающими скобками.
Здравствуйте, Великий Мессия, Вы писали:
BFE>>И вообще, зачем формат, если это потоковый вывод?
ВМ>если потоковый вывод подразумевается iostream ВМ>то он по скорости давно уже позади того же fmt/std::format ВМ>бенчмарки погугли
Почему именно iostream ? Можно написать намного быстрее.
ВМ>во первых как сказал выше, это тормозно
Вот как написали, так оно и будет.
ВМ>во вторых, глазами теряется общий формат строки, иногда и часто это важно
Это вообще не аргумент. Вот в этой строке "{prefix}-{errno}: got {calculate(bits)} for {bits:#06x}" вообще всё потеряно. И это ещё инициализации , типа int{} туда не засунули.
Я понял бы аргумент про перевод на другой язык, где местами надо менять аргументы вывода, но не этот.
BFE>>
BFE>>Я ещё могу понять, что некоторым не нравятся "шевроны", но тогда было бы логично предложить какой-нибудь приличный синтаксис для потока, а не вот это вот всё с закрывающими и открывающими скобками. ВМ>вот и используй fmt/std::format
Я его и использую, для форматированного вывода. А для потокового использую потоки.
Здравствуйте, 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>>>Я ещё могу понять, что некоторым не нравятся "шевроны", но тогда было бы логично предложить какой-нибудь приличный синтаксис для потока, а не вот это вот всё с закрывающими и открывающими скобками. ВМ>>вот и используй fmt/std::format BFE>Я его и использую, для форматированного вывода. А для потокового использую потоки.
чудесно, для потокового вывода, когда и где скорость не важна, отличный выбор
но мы говорим о другом случае
Здравствуйте, B0FEE664, Вы писали:
BFE>А зачем? BFE>Чем это лучше:
Тем что форматипованную строку можно целиком сохранить, например для переводчиков, и потом целиком же единую строку и выводить, а не разбивать на кучу подстрок
Здравствуйте, B0FEE664, Вы писали:
BFE>А зачем? BFE>Чем это лучше: BFE>
BFE>std::string str = "a = " + std::to_string(var);
BFE>
Медленно и многословно.
BFE>И вообще, зачем формат, если это потоковый вывод?
Потоковый вывод и интерполяция строк это теплое и мягкое. Суть интерполяции это компактное по записи и оптимальное по скорости построение цельной строки, а не последовательное сохранение чего куда-то.
Другое дело, что я не уверен, что в С++ это нужно, тем более на уровне ядра языка. В C# философия одна, там очень ценны разные инструменты быстрого написания прикладного кода, в С++ же, если код пестрит такими вот "интерполяциями", то, скорее, что-то не то с архитектурой.
Здравствуйте, Hоmunculus, Вы писали:
H>Тем что форматипованную строку можно целиком сохранить, например для переводчиков, и потом целиком же единую строку и выводить, а не разбивать на кучу подстрок
Сохранять "форматипованную" (что бы это не значило) строку содержащую имена локальных и глобальных переменных — так себе идея. Переименование переменной, изменение зоны видимости, добавление локальной переменной перекрывающую переменную в строке => проблема.
Здравствуйте, Went, Вы писали:
BFE>>А зачем? BFE>>Чем это лучше: BFE>>
BFE>>std::string str = "a = " + std::to_string(var);
BFE>>
W>Медленно и многословно.
Точно медленно?
А многословно — чем плохо? Читать же легче.
BFE>>И вообще, зачем формат, если это потоковый вывод? W>Потоковый вывод и интерполяция строк это теплое и мягкое. Суть интерполяции это компактное по записи и оптимальное по скорости построение цельной строки, а не последовательное сохранение чего куда-то.
Не понял, почему "оптимальное по скорости построение цельной строки"? Откуда это следует?
А то, что компактное — это не всегда хорошо.
Здравствуйте, Великий Мессия, Вы писали:
ВМ>смотря кому и кто с чем работает ВМ>не беря твой любимый потоковый << вывод ВМ>любые sprintf/fmt/std::format где внутри длинная строка(а это ускоряет если не склеивать потом эти строки)
В потоках вообще нет операции выделения динамической памяти и склеивать строки не надо. Так за счёт чего потоковый вывод (если он написан оптимально) возможно обогнать?
ВМ>то можно спутать аргументы и потерять всякие переводы строк итд
Спутать аргументы и потерять всякие переводы строк для форматированной строки так же легко, как и для потока.
Здравствуйте, Великий Мессия, Вы писали:
ВМ>ответ Антона — что то типа, разработчики компиляторов протестуют/бунтуют, короче не хотят, для них это якобы сложно
Посмотрел, наконец, видео и понял, что разработчики компиляторов правы.
Правильно говорят, что с подобной строкой будут схожие проблемы, что и с std::initializer_list.
Так же в видео правильно было замечено, что введя суффикс для строки, теоретически можно реализовать то же самое не меняя язык (а только библиотеку).
Я так понимаю, что при наличии рефлексии обеспечить, например, для строки
"a = {var}"_F
вызов
std::format("a = {}", var)
должно быть не очень сложно, даже при отсутствии списка локальных переменных. Но для этого надо иметь возможность протащить захват локальных переменных в literal operator...
Здравствуйте, B0FEE664, Вы писали:
BFE>>>Чем это лучше: BFE>>>
BFE>>>std::string str = "a = " + std::to_string(var);
BFE>>>
W>>Медленно и многословно. BFE>Точно медленно?
Ну, в приведенном выше случае разница сомнительна, но если мы подставляем несколько объектов в некоторый текст, то при конкатенации многократного копирования не избежать. А умная, оптимизированная интерполяция может предугадать необходимый размер (или использовать один заготовленный большой временный буфер), и лишнего копирования избежать. Или я ошибаюсь?
BFE>А многословно — чем плохо? Читать же легче.
Мне легче прочитать:
auto str = $"a = {var}";
BFE>Не понял, почему "оптимальное по скорости построение цельной строки"? Откуда это следует?
См. выше. BFE>А то, что компактное — это не всегда хорошо.
В прикладном коде — хорошо. У меня, например, проект — по сути гигантский кодогенератор на C#. Там интерполяция, как говорится, "что доктор прописал".
Здравствуйте, sergii.p, Вы писали:
SP>как раз быстро https://quick-bench.com/q/AHUvx7pCnwWGf1b7esOLgCB4G7s SP>Для таких простейших случаев простая конкатенация проще и быстрее.
Я думал, мы обсуждаем общий случай, когда у нас 2,3 и более плейсхолдеров.