Комментарии 64
Гхкм, а что мешает ручному вызову деструктора? "Не идиоматично"?
Последнее - это constexpr, constinit и consteval.
Так об этом и речь. consteval и constinit ведь ввели, чтобы уж точно отработало при компиляции, а не когда-то там. Вот и сделали бы прямое переключение между кодом для исполнения и кодом для компиляции.
в рефлексии появился consteval { ... } блок как раз)
Найти бы ещё его описание. И внутри него можно пройтись по списку типов без шаблонной магии?
constexpr auto members = std::array{^^int, ^^char, ^^float};
auto tup = std::make_tuple(typename [: ...members :]{}...);Нечто такое должно быть можно. Есть и template for.
godbolt.org говорит, что не может разобрать.
#include <array>
void foo() {
constexpr auto members = std::array{^^int, ^^char, ^^float};
template for(constexpr auto t : members) {
typename [: t :] x = 0;
}
}Вот такой код вполне себе разбирает. https://godbolt.org/z/ec91doMaY
Описание не читаем, но уже говорим что рефлексию добавляют костыльным способом.
Модель объектов C++ наверняка не знаем, но критикуем конструкторы и предлагаем "объекты значения" которые не вызывают конструкторов и что-то делают под капотом.
Многое из предлагаемого уже можно делать, пусть и не самым эргономичным способом.
Технический уровень очень низкий, такое публиковать - позор для специалиста.
Описание не читаем, но уже говорим что рефлексию добавляют костыльным способом.
Технический уровень очень низкий, такое публиковать - позор для специалиста.
Странно, если все такие умные, то почему SFINAE устарел, пользовались бы дальше. Или великость помешала сразу нормально сделать и надо было перед другими похвастаться: “Мам, сматли как я на блейнфаке шаблоны велтеть умею”. А потом ошибки компиляции на несколько листов, и несколько секунд на компиляцию пустого файла, потому что компилятор в прекомпилированном заголовке шаблоны инстанцирует.
которые не вызывают конструкторов
Во-первых, вы видите разницу между “не вызывают конструкторы” и “не вызывают конструкторы лишний раз”? Во-вторых, речь об объектах на стеке. В-третьих, большие и сложные объекты на стеке обычно не хранят, а всякую мелочь можно и на месте данными заполнить.
Многое из предлагаемого уже можно делать, пусть и не самым эргономичным способом.
Хотя казалось бы, практически вся статья об эргономике. Но ладно, брейнфак так брейнфак. Скормим всё ИИ, пусть он за нас ману токены тратит.
Странно, если все такие умные, то почему SFINAE устарел, пользовались бы дальше. Или великость помешала сразу нормально сделать
Возможно, вы еще очень молоды и не застали эпопею с включением концептов в стандарт. Которая была очень долгой и болезненной. Ведь их (концепты) хотели включить еще в C++0x, который в итоге стал C++11 без концептов. А допилили концепты только к C++20.
Мешала не “великость”, а сложность задачи.
По компонентам есть Boost, там есть всё, но слишком много :)
Да да, и не только буст, но и ещё куча библиотек, кто во что горазд. А потом всё это место на диске и в кэше процессора занимает. И это не отменяет тезиса о том, что надо шарить по интернету в поисках, качать огромные либы типа буста, в которых "всё есть", подключать различными способами и т.д.
Как называется dll из boost для работы с json? То-то и оно.
так по слушайте, языки, к которым вы здесь хотите притянуть С++, занимают аппаратные ресурсы несоизмеримо больше. К примеру, переменная типа Boolean в питоне будет занимать минимум 24 байта
“худшее в жизни системного программиста — это когда не‐системщики думают, что осознают всю глубину трагедий, из которых она состоит”
В линуксе же как-то обобщили. Как думаете, сколько занимает bool в подобных библиотеках? Они уже по факту используются, только надо привести их к более употребимому виду. Например, убрать com-порт из Qt в отдельную либу, потому что его наличие в графической либе - это нонсенс.

Убедиться, что объект не используется после передачи в функцию, требует прохода, который обычно делает оптимизатор. Также нет гарантии, что хоть и объект дальше не используется, его можно сразу же переместить и уничтожить. Это сломает текущие гарантии о жизни объектов, так же, как и второй тезис про instant деструктор — уничтожение происходит в порядке LIFO.
Деманглинг имён сломает ABI, это наша больная тема(
Про json мне нечего сказать, но знаю, что с добавлением стандартных сетевых функций есть такие проблемы как быстрое реагирование на уязвимости, что комитет не сможет удовлетворить, так как выпуск происходит раз в три года на данный момент.
float cos_table[100];
compile_time {
for (int i = 0; i < 100; ++i)
cos_table[i] = std::cos(i);
}Про constexpr уже написали, но вот в этом коде может быть не совсем очевидно как сделать, а сделать это можно с помощью IILE:
#include <algorithm>
#include <array>
#include <cmath>
constinit auto cos_table = []() { // constinit не обязателен, но хорошая гарантия
std::array<float, 100> table;
std::ranges::generate(table, [i = 0] mutable { return std::cos(i++); });
return table;
}();Убедиться, что объект не используется после передачи в функцию, требует прохода, который обычно делает оптимизатор.
Вот и пусть делает.
Также нет гарантии, что хоть и объект дальше не используется, его можно сразу же переместить и уничтожить.
И именно поэтому предлагаю добавить тег для объектов или классов, которым это надо. Я же говорю, приведите конкретные примеры, причём желательно классов не из стандартной библиотеки. Это не так просто.
есть такие проблемы как быстрое реагирование на уязвимости
Так комитету и не надо над каждой либой сидеть. Я же потому и не в пространство имён std, а в sal их предлагаю. Достаточно обговорить формат и общие правила построения либ, а всё остальное сделать как в pip: не нравится либа - идёшь и накатываешь новую версию.
Про constexpr уже написали, но вот в этом коде может быть не совсем очевидно как сделать, а сделать это можно с помощью IILE
Ну вот, начинается брейнфак. И, главное, зачем? Разве мой вариант менее понятный или менее универсальный? Его даже в C можно использовать.
А если объект используется после вызова функции в другом потоке, как он должен это определить? Даже если этот флаг сделать, как отслеживать, что объект на самом деле не используется в дебрях лапшекода?
Давайте пример кода. Отслеживать по упоминанию объекта в коде функции. goto уже не используют, код нынче не столь похож на лапшу. Найти последний блок, в котором было упоминание объекта и можно удалять.
Допустим у вас есть коммуникация, на начальной стадии проекта синхронная. То есть пакет формируется, отправляется, больше он не нужен можно удалять. Проект разросся и синхронная коммуникация стала ботлнэком. Решили переписать на асинхронный через калбэки, и тут уже никто не помнит, что там что-то где-то удаляется с флагом, и это нужно убрать. Это так с наскоку пример.
Может даже концепцию “значения” стоит распространить на вычисление выражений,
string("asd") + string("fgh")- здесь ни к чему дёргать конструкторы с деструкторами. А ещё, возможно, такconstexprсможет получаться автоматически.
Можете тогда предложить свой вариант того, как это могло бы выглядеть? Нужно ведь понимать, что std::string достаточно честный тип, который находится в стандартной библиотеке. Как это совместить со всем остальным в языке? К примеру, с тем же std::vector, std::variant, placement new и ручным управлением времени жизни объекта. constexpr и так получается практически автоматически, достаточно лишь constexpr приписать ко всему (да и if consteval блоки там, где компилятор не может вычислить куски в constexpr, но это более редкий случай).
Это чуть ли не самое очевидное изменение. Почему у питона есть стандартные прикладные библиотеки типа json, xml и т.д., а когда хочешь прочитать json на C++, надо бегать искать нормальную библиотеку и пытаться подключить.
Boost уже стал второй стандартной библиотекой. Если не важно то, что сам Boost это достаточно тяжелая зависимость, то можно брать его, хотя и не всё там сделано в самом удобном виде, да и не всё есть.
Ну и конечно, сами библиотеки должны быть сишными (с нормальными именами функций то есть), глядишь, и другие языки на них пересядут. Пишешь
pic install requestsи получаешь библиотеку requests с помощью Pack Installer C - удобно же?
Про имена функций непонятно (буду дальше описывать что если бы Вы предлагали обязать их работать и через C апи в том числе). А что Вы предлагаете делать с библиотеками вроде Boost.Hana, которые целиком на шаблонах сделаны? С таким подходом нельзя будет делать фактически ничего, что делает C++ самим собой. C++ без исключений, шаблонов и constexpr уже сложно назвать C++. С пакетными менеджерами уже давно есть CPM.cmake, да и можно использовать пакетные менеджеры ОС. У некоторых из них возможностей вполне достаточно. К примеру, nix.
Код, запускаемый на этапе компиляции
Так и не ясно, чем это было бы лучше подхода с constexpr сейчас. С деталями тоже неясно. Так и в предоставленном варианте нет возможности в этом блоке переиспользовать другие элементы, которые были вычислены в предыдущих. Оно всё равно потребует в данных фиксации того, что они вычислены на этапе компиляции, ведь компилятору это определить нетривиально, т.к. проблема останова и прочее.
Контейнеры с типами, чтобы не мучать компилятор шаблонами с переменным числом аргументов
Уже есть в виде std::meta::info и любых контейнеров, которые умеют хранить значения (к примеру, std::vector). Смотреть рефлексию для C++26.
Кодогенерация
Реализовывать Вы это как собрались? Предположим, что в таком блоке для "выражений" будет добавлено что-то, что закроет функцию и начнёт новую. Тогда реализация крайне нетривиально. Но есть и более важная проблема. В C++ шаблонах компилятор может заранее парсить их тело, ещё до их инстанцирования. Если там будут произвольные варажения, то это сломает эту модель и до инстанцирования о шаблонах нельзя будет сказать практически ничего.
Хорошо, предположим, что они такие блоки могут возвращать только специальные куски AST. Тогда эта модель с некоторыми изменениями кое-как, но работать может, хотя и сильно сузит возможности для кодогенерации. Но возникает один вопрос зачем это всё? Намного более гибким будет подход с возможностью задать новую функцию/тип/прочее через расширение к compile time рефлексии в C++26 с нужным именем, а после уже определить там тело через типы плюсового AST в стандартной библиотеке (можно и немного сахара для такого придумать, но необязательно).
Можно было бы изучить вопрос получше, а не сразу выкидывать про это на Хабр? Или Вы воспринимаете Хабр как место получения критики идей и их развития? Если так, то это имеет смысл. Но в итоге это должно не на Хабре дальше быть с таким, а развивать до зрелости подхода и пойти в пропозал для стандарта.
Можете тогда предложить свой вариант того, как это могло бы выглядеть?
Потому и написал “может”, что это очевидно на стороне пользователя, но не компилятора. Можно предположить такое: если в выражении участвуют POD-типы, то можно посчитать результат и вписать в память. Если используются указатели на POD, то можно так же посчитать результат, выделить память и заполнить.
достаточно лишь constexpr приписать ко всему
О том и речь, чтобы не приписывать.
Boost уже стал второй стандартной библиотекой
Забиваем в поисковик “как прочитать json в python” и видим предложение использовать стандартный модуль json. Потом там же пробуем “как прочитать json в C++”, и там не видно boost. А ещё могу по второму разу спросить, как в boost называется dll, которая читает json? И да, он тяжёлый, и это проблема. В питоне хоть на маке, хоть на винде импортируешь нужную либу через pip и в продакшен. То есть вопрос не в возможности как таковой, а в пользовательском опыте. C++ просто неудобно пользоваться.
А что Вы предлагаете делать с библиотеками вроде Boost.Hana, которые целиком на шаблонах сделаны?
Предлагаю ничего не делать. Нам же не обязательно что-то сделать со всеми библиотеками в мире, достаточно добавить в SAL самые часто используемые вещи. Ну и собственно, шаблоны и шаблоны, вроде как никто не говорил, что в SAL не должно быть инклюдов. С-шники не будут плакать, если не смогут воспользоваться именно этим модулем, кому надо, тот и импортирует. Да и в принципе никто не мешает сделать отдельно папку с C-инклюдами, отдельно с C++. Вот там можно обёртки из классов написать и исключения кидать.
Так и не ясно, чем это было бы лучше подхода с constexpr сейчас
Это лучше прозрачностью написанного. Насчёт порядка выполнения блоков - тут да, надо подумать. Может обязать пользователя вручную это гарантировать, вызывая функции инициализации вручную.
Реализовывать Вы это как собрались? Предположим, что в таком блоке для “выражений” будет добавлено что-то, что закроет функцию и начнёт новую.
Это уже что-то из раздела ifdef вокруг имён функций пошло, наверное не стоит давать пользователям выходить за границы блока.
Можно было бы изучить вопрос получше, а не сразу выкидывать про это на Хабр?
Озвучил то, с чем сталкивался за 10 лет работы с плюсами, без пользовательских литералов можно обойтись, а без стандартной библиотеки не удобно. Может кто-то более шарящий и пропосал сделает.
Потому и написал “может”, что это очевидно на стороне пользователя, но не компилятора. Можно предположить такое: если в выражении участвуют POD-типы, то можно посчитать результат и вписать в память. Если используются указатели на POD, то можно так же посчитать результат, выделить память и заполнить.
А можно увидеть какое-то более подробное описание алгоритма? И какое отношение имеет std::string к POD типам?
О том и речь, чтобы не приписывать.
Суть в чём? Чтобы функция могла считаться constexpr по умолчанию? Но подозреваю, что могут возникнуть некоторые проблемы.
Забиваем в поисковик “как прочитать json в python” и видим предложение использовать стандартный модуль json. Потом там же пробуем “как прочитать json в C++”, и там не видно boost. А ещё могу по второму разу спросить, как в boost называется dll, которая читает json? И да, он тяжёлый, и это проблема. В питоне хоть на маке, хоть на винде импортируешь нужную либу через pip и в продакшен. То есть вопрос не в возможности как таковой, а в пользовательском опыте. C++ просто неудобно пользоваться.
Зачем мне знать про какие-то там dll-ки? Какое отношения они вообще имеют к вопросу? Опять же, существуют CPM.cmake и nix, с которыми подключить библиотеку дело достаточно быстрое и удобное.
Предлагаю ничего не делать. Нам же не обязательно что-то сделать со всеми библиотеками в мире, достаточно добавить в SAL самые часто используемые вещи. Ну и собственно, шаблоны и шаблоны, вроде как никто не говорил, что в SAL не должно быть инклюдов. С-шники не будут плакать, если не смогут воспользоваться именно этим модулем, кому надо, тот и импортирует. Да и в принципе никто не мешает сделать отдельно папку с C-инклюдами, отдельно с C++. Вот там можно обёртки из классов написать и исключения кидать.
Предлагаете тогда не закидывать туда огромную кучу нормальных библиотек, а оставить только библиотеки без шаблонов? К примеру, Boost.Asio много использует шаблоны достаточно много, range-v3, ctre и т.д.
Зачем вообще он нужен будет тогда, когда там нет огромного количества полезных и используемых библиотек?
Зачем вообще ограничиваться только теми, у которых есть и C-апи? Плюсы это ведь не "Си с классами", а сильно более продвинутый язык.
Это лучше прозрачностью написанного. Насчёт порядка выполнения блоков - тут да, надо подумать. Может обязать пользователя вручную это гарантировать, вызывая функции инициализации вручную.
Не наблюдаю тут никакой прозрачности. Можете рассказать про неё подробнее?
наверное не стоит давать пользователям выходить за границы блока.
На что ниже у меня там тоже есть свой комментарий.
А можно увидеть какое-то более подробное описание алгоритма? И какое отношение имеет std::string к POD типам?
Мне как-то приходилось компилятор править, так что при некотором желании можно, но сейчас наверное нет смысла. В компиляторе же есть упрощение выражений, состоящих из констант, типа (4+5)*6. Некоторая интерпретация кода вроде тоже есть. Тут конечно вопрос, как добраться до кода функций, остаётся полагаться на то, что они в заголовочном файле.
std::string хоть и не pod, но в ней какие-то инты и указатель на массив pod’ов, можно и это попробовать проинтерпретировать.
Зачем мне знать про какие-то там dll-ки? Какое отношения они вообще имеют к вопросу?
Какое отношение динамические библиотеки имеют к вопросу о стандартных библиотеках? Даже не знаю. Расслабились все, место на диске не жалеют. Скачал clang, а там пачка почти одинаковых exe’шников по 100 с лишним мегабайт весом.
Опять же, существуют CPM.cmake и nix
Что-то узкоспециализированное. nix вообще с трудом гуглится. Если речь про язык программирования, то говорить, что в C++ что-то есть, ссылаясь на другой язык, ну не знаю.
Предлагаете тогда не закидывать туда огромную кучу нормальных библиотек, а оставить только библиотеки без шаблонов?
Если что-то похожее на стандартное, ну ок, закидывайте.
Зачем вообще он нужен будет тогда
Чтобы всё доступное быстренько скачать, а с остальным уже возиться.
Мне как-то приходилось компилятор править, так что при некотором желании можно, но сейчас наверное нет смысла. В компиляторе же есть упрощение выражений, состоящих из констант, типа (4+5)*6. Некоторая интерпретация кода вроде тоже есть. Тут конечно вопрос, как добраться до кода функций, остаётся полагаться на то, что они в заголовочном файле. std::string хоть и не pod, но в ней какие-то инты и указатель на массив pod’ов, можно и это попробовать проинтерпретировать.
Как Вы это в стандарт описывать собираетесь? И зачем так делать?
Какое отношение динамические библиотеки имеют к вопросу о стандартных библиотеках? Даже не знаю. Расслабились все, место на диске не жалеют. Скачал clang, а там пачка почти одинаковых exe’шников по 100 с лишним мегабайт весом.
Так дело в том, что мне вообще нет дело до dll-ек. Я подключаю библиотеку в CMake, а дальше уже само находит и подключает. До уровня .dll опускаться смысла нет.
Что-то узкоспециализированное. nix вообще с трудом гуглится. Если речь про язык программирования, то говорить, что в C++ что-то есть, ссылаясь на другой язык, ну не знаю.
Nix это не только язык, но ещё и ОС и пакетный менеджер. nixos.org.
CPM.cmake это просто вспомогательные cmake скрипты для подключения пакетов. Используется, к примеру, в userver. https://github.com/cpm-cmake/CPM.cmake
Если что-то похожее на стандартное, ну ок, закидывайте.
Вы так и не ответили на то, а зачем нужно такое с C апи?
Как Вы это в стандарт описывать собираетесь? И зачем так делать?
Ни разу не пробовал, так что не знаю. А делать так для оптимизации кода. Возможно, стандарт должен разрешить дополнительно оптимизировать код для объектов без тега. Примерно как с volatile, если переменная помечена таким тегом, тогда все чтения и записи делаем скурпулёзно, а если нет, то оптимизируем.
Так дело в том, что мне вообще нет дело до dll-ек. Я подключаю библиотеку в CMake, а дальше уже само находит и подключает. До уровня .dll опускаться смысла нет.
После чего пользователи начинают жаловаться, что у них dll не хватает. Или, допустим, запускаешь свою прогу, а она подхватывает dll от notepad++ и делает что-то не то.
Вы так и не ответили на то, а зачем нужно такое с C апи?
Уже где-то писал, чтобы другие языки тоже могли использовать эти библиотеки. А если речь про конкретно библиотеку для метапрограммирования, то понятно, что ей C апи не нужен.
Ни разу не пробовал, так что не знаю. А делать так для оптимизации кода. Возможно, стандарт должен разрешить дополнительно оптимизировать код для объектов без тега. Примерно как с volatile, если переменная помечена таким тегом, тогда все чтения и записи делаем скурпулёзно, а если нет, то оптимизируем.
Стандарт и так разрешает оптимизировать код. Компилятор имеет право вырезать лишние конструкторы, деструкторы и прочее. Только есть разница в том, что считается наблюдаемыми эффектами. Если аллокации такими не считать, то компилятор будет иметь право работать и с длинными std::string (когда не срабатывает SSO).
После чего пользователи начинают жаловаться, что у них dll не хватает. Или, допустим, запускаешь свою прогу, а она подхватывает dll от notepad++ и делает что-то не то.
Первый раз слышу про такие проблемы. Но у меня и с виндой опыта разработки нет, 100% кода пишу на лине.
Уже где-то писал, чтобы другие языки тоже могли использовать эти библиотеки. А если речь про конкретно библиотеку для метапрограммирования, то понятно, что ей C апи не нужен.
Не такое уж и значительное преимущество.
Вы за 10 лет не осилили прочесть "The Design and Evolution of C++"? После ее прочтения обычно половина таких вопросов отпадает.
Эхе-хе, помню, в 17 стандарте вроде что-то про инициализацию переменных добавили, в 20 обратно откатили. Ещё меня как-то попросили дать ссылку на хороший код. Полез в исходники clang’а, а там такие нечитабельные трёхэтажные выражения, с целью оптимизации наверное. Да и вообще оказалось, что красивый код сложно найти. После такого вопросы, наоборот, возникают )
Про генерацию кода во время компиляции - это уже отдельный этап Compile-time, который явно появился в Zig (Comptime называется)
А по библиотеке компонентов - было бы неплохо читать JSON/XML и другие конфиг форматы во время компиляции, и заполнять структуры и тд. Удобная штука на самом деле, но опять же "никакая строка не должна быть переписанная, будь она написана в 1986 или 2026"
От себя могу добавить как идею (хотя я уже потихоньку это реализовываю для своего движка) - делать public/protected поля с указанием кому именно они относятся. Пример: "public(FRenderer, FPhysics): ....". И тогда поле как бы является публичным, но только если обращение идет из класса/структуры FRenderer или FPhysics. Получается такой своеобразный "умный friend" (так как мы не раскрываем прям все поля и методы, как это делает обычный friend)
Странный поток мысли. Какой учёт конструкторов? Кто его ведёт? Ничего непонятно. Рво нрво выполняется автоматически компилятором. Кто требует пепемещения? Наверно тот же кто ведет учет конструкторов... чем человеку скобочки не угодили? Как вызывать конструкторы раньше? Наверно отделной языковой конструкцией! Давайте добавим) хотя есть delete и явный вызов. Большая часть батареек питона давно села, для джейсона либ хоть попой жуй, с десятками тысяч звёзд, тут уж каждый первый c++ задрот считает делом чести поабъюзить сфине. Про constexpr я вообще ничего не понял...
Рво нрво выполняется автоматически компилятором.
Там вполне конкретный код приведён, и там RVO/NRVO не применяется, была по этому поводу на Хабре статья.
чем человеку скобочки не угодили
Видимо своим наличием. Зачем их писать, если можно было бы не писать без потери в скорости.
для джейсона либ хоть попой жуй
Ага, и вы это подаёте как достоинство, хотя вообще-то это недостаток, о чём в статье и говорится. Попробуйте ответить на вопрос, почему они продолжают плодиться, и почему в питоне не плодятся
Попробуйте ответить на вопрос, почему они продолжают плодиться
Потому что в отличие от python от программ на С++ ожидается эффективность в ресурсах, а так как разным проектам нужны абсолютно разные функции, и накладные расходы тоже могут быть разные, все выбирают то что им больше подходит. Или пишут свое.
У меня была ситуация, когда я не мог использовать "стандартный" в проекте сериализатор в json, потому что он в потоковую запись не умел.
Вообще многое что вы пишите противоречит фундаментальным принципам С++, которые его и сделали таким каким мы его сейчас знаем.
Один из фундаментальных принципов: не оптимизируй код заранее. Все так обоптимизировались, что компилятор на пустой файл может 5 секунд тратить. У вас была ситуация, когда стандартный сериализатор не умел в потоковую запись, а у кучи людей было, что проще сделать на питоне, потому что в сях же с библиотеками возиться.
Так-то люди свои строки, векторы и аллокаторы пишут, когда сильно быстро надо, но это не общий случай.
Причем тут преждевременные оптимизации? Углубитесь пожалуйста в историю языка, вам станет гораздо понятнее мотивация многих решений и в целом философия языка.
Кокретный код это вот тут?
auto a = b + c;
f(a);А где тут вообще (N)RVO кейс мог бы быть?
Зачем какието теги для (N)RVO если это оптимизация на усмотрение компилятора (на чиная с 17 даже строже)? Зачем её явно запрещать или разрешать? Конструкторы и RVO это перпендикулярные вещи.
Мажорных либ 2 - rapidJson и nlohmannjson. В Qt своя хорошая реализация.
Конструкторы и RVO это перпендикулярные вещи.
Ну как же. (N)RVO это copy elision, что с конструкторами связано настолько прямо, настолько возможно. Выражение (N)RVO как таковое в стандарте вообще не используется.
А где тут вообще (N)RVO кейс мог бы быть?
Ни где, и вроде даже не утверждается ни где, что он мог бы быть. Речь о том, чтобы компилятор, если он видит, что один из объектов дальше использоваться не будет, не создавал копию, а использовал оригинал, не думая о том, что возможно, программист действительно хотел получить вызов копирующего конструктора. Пойдите и посчитайте, сколько раз в проекте вызывается std::move, в удобном языке должно быть в районе 0.
Зачем какието теги для (N)RVO если это оптимизация на усмотрение компилятора (на чиная с 17 даже строже)? Зачем её явно запрещать или разрешать? Конструкторы и RVO это перпендикулярные вещи.
Вот вы мне и ответьте, зачем какие-то теги, и почему в этой статье народу идея с тегами зашла.
Наконец, хотя этот предмет не из приятных, я должен упомянуть PL/1, язык программирования, документация которого обладает устрашающими размерами и сложностью. Использование PL/1 больше всего напоминает полет на самолете с 7000 кнопок, переключателей и рычагов в кабине. Я совершенно не представляю себе, как мы можем удерживать растущие программы в голове, когда из-за своей полнейшей вычурности язык программирования — наш основной инструмент, не так ли! — ускользает из-под контроля нашего интеллекта. И если мне понадобится описать влияние, которое PL/1 может оказывать на своих пользователей, ближайшее сравнение, которое приходит мне в голову, — это наркотик. Я помню лекцию в защиту PL/1, прочитанную на симпозиуме по языкам программирования высокого уровня человеком, который представился одним из его преданных пользователей. Но после похвал в адрес PL/1 в течение часа он умудрился попросить добавить к нему около пятидесяти новых “возможностей”, не предполагая, что главный источник его проблем кроется в том, что в нем уже и так слишком уж много “возможностей”. Выступающий продемонстрировал все неутешительные признаки пагубной привычки, сводящейся к тому, что он впал в состояние умственного застоя и может теперь только просить еще, еще, еще. Если FORTRAN называют детским расстройством, то PL/1, с его тенденциями роста подобно опасной опухоли, может оказаться смертельной болезнью.
Э.Дейкстра, Смиренный программист, 1972
Но что будет если пойти по обратному пути уменьшения возможностей? Получится такой мерзотный язык как Go. Язык должен быть удобным инструментом для использования, а не удобным для освоения. В том же Go пошли обратным путем и сделали язык очень простым, но и максимально неудобным. Те же генерики ввели вот только недавно, а ведь такие средства для создания общего кода максимально полезная вещь.
Как по мне, в плюсах возможностей всё ещё недостаточно, а с каждым стандартом язык становится лучше. Но и возможности ради возможностей тоже не будут хороши. Они должны хорошо вписываться в язык, не должны приводить к бессмысленному росту языка, но должны приводить к его развитию. Лучше добавлять общие и гибкие решения, а всё остальное наслаивать уже на них, а не добавлять "адхоки" на каждый случай.
Я считаю Go прекрасным языком.
И нет, это не мой первый язык, и я отнюдь не новичок в профессии.
Я считаю Go прекрасным языком.
Ключевое здесь “я”.
И нет, это не мой первый язык, и я отнюдь не новичок в профессии.
Есть ненулева вероятность, что вы просто все это время работаете над проектами, в которых более чем достаточно Си или Go. И, как следует из множества разговоров с вами (что здесь, то на RSDN), C++а вы и не знаете, особенно современного. Но мнение имеете и старательно его доносите до окружающих, хотя C++ вас использовать никто не заставляет. Оставили бы вы C++ для тех, кто (в отличии от вас) не хочет пердолиться с Си.
Угадайте, в каком языке форматирование делается так же, как в std::format. Часть пунктов направлена скорее на упрощение, чем на усложнение, чтобы не тратить ману на расстановку std::move, например.
В чем проблема, сваять очередную версию С в которой будет всё перечисленное.
Кто мешает тебе выдумать порох непромокаемый? (С)
спасибо за статью, моё диллектанское чутье на эту тему наводит меня на такой пример,
#include <std> //пространство базовое
import <string>// импорт наполняет пространство возможностями, базовое пространство не надо прописывать
//всё функции, убрать воид, и указывать явно тип если он нужен
class Test{
int a;
Test(){
//constructor()
}
~Test{
//autodestructor()
}
}
class Test1<T>{
int b;
Test1(){
//constructor()
}
~Test1{//сделать тильду невызываемую, а брекетом автоудаление после выхода
//autodestructor()
}
}
int main(){
auto a = Test::Test();
auto b = Test1::Test1<int>();
return 0;
}но проблема в том, что на поверхности синтаксиса С++ столько, что такой очевидный синтаксис придётся комментировать килотонной документации, хотя это на поверхности и должно было быть очевидным.
Может быть переключитесь на Rust, многабукафнечитал, но как будто там почти всё вышеописанное сделано удобно, а не неудобно как в c++ =)
Раст сам по себе не лучший язык. Даже шаблонов из C++ нет. Вся работа с кодогенерацией работает через его макросы, которые работают с текстом, а не с типами. Всё ли в расте с аналогом constexpr хорошо? https://godbolt.org/z/sn3cbPYKz и даже не заифать https://godbolt.org/z/TGaGPP37c
В расте нет и исключений (они как-бы есть в виде паник, но кто их применяет везде?).
Перегрузок в расте нет.
Рефлексии в расте тоже нет, когда в плюсах она есть.
Перегрузок в расте нет.
И слава богу! И пускай никогда не будет! Худшая фича С++! Сколько от неё страданий)
Сделали бы перегрузки допустимыми только для операторов - цены бы им не было.
В расте нет и исключений
И зачем они?
Рефлексии в расте тоже нет
В том виде в котором она есть в С++ - нет. Но процедурные макросы ничем не хуже, а даже лучше.
Ну и С++26 ещё не приняли, в значит и в плюсах её тоже нет.
надо бегать искать нормальную библиотеку и пытаться подключить.
ну прям так и "бегать". Какие все ленивые стали с питонами и пр. Просто пару кнопок нажать, а по большей части только заголовок подключить - ничего нет в этом сложного.

Чего не хватает в С++