Здравствуйте, Pzz, Вы писали:
S>>Go — это сборщик мусора, тащить за собой всю среду не оно. Как и .Net.
Pzz>.Net ташит за собой рантайм в виде кучи файлов. Go просто линкует программу статически.
Native AOT все в одном файле с урезанием. Там из рантайма только сборщик мусора несколько сотен килобайт.
Да и обычный .Net со всем рантаймом можно в 1 файл.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Marty, Вы писали:
M>>>А в чем проблема? BFE>>Это отход от принципа "не платим за то, что не используем." M>Так постоянно используется. Да и завершающий 0 — смешная плата
Это минимум одно присвоение на каждое добавление символа.
M>>>Завершающий ноль — для совместимости с сишными АПИ. BFE>>Для совместимости было бы логично завести отдельный класс. M>И туда-сюда конвертить?
Если надо.
M>А такая строка, без завершающего нуля — уже есть. Называется std::vector<char>
Это не строка: у него нет многих строковых методов find..., substr, compare, оператора сложения...
Опять же: вектор — не лучший выбор.
M>BSTR — это вообще частный случай строк в одной из технологий на одной из платформ.
Нет. Это просто название от MS, а сама методика хранения длины строки перед указателем пришла из UNIX, насколько я знаю.
M> Можешь сделать сам класс для BSTR. Хотя стоп, такие классы вроде уже есть в MFC/ATL. Не помню, правда, есть ли там конвертация в/из std::string. Можешь дописать
Написать то я могу всё что угодно, но проблема в том, что потом каждому сотруднику придётся это изучать, чтобы развивать код, а обычный программист ой как не любит изучать "велосипеды".
M>А зачем тебе отдельно С++ строка и С строка? Чтобы при вызове сишного АПИ было дополнительное преобразование?
А зачем мне C вызовы?
M>>>Не понял, когда это эта проблема с самого начала существовала? У вектора, у строк, у деки, у других контейнеров всегда была версия конструктора, принимающего count и значение элемента, которым надо заполнить. Никогда с этим не было никаких проблем.
В каком-то смысле — да, с самого начала. У конструктора с двумя параметрами очень сложная имплементация.
BFE>>Да, был не прав, конечно, у других контейнеров std конструкторы с двумя параметрами имеют ту же проблему: по виду x(a, b) который из двух конструкторов вызовется сказать нельзя — надо знать типы a и b. Разрешали и разрешают эту ситуацию с помощью метапрограммирования. M>Надо просто запомнить, что первым аргументом идёт count, вторым — значение элемента. Так как у всех контейнеров это сделано единообразно, запомнить не так уж сложно. Также есть метод assign с такой же сигнатурой. Всё несколько сложнее:
Какого размера вектора v1 и v2 ?
Есть ли какие либо проблемы с векторами v4, v5 и v6?
M>Ни разу не приходилось использовать метапрограммирование для использования таких конструкторов. Зачем? Для чего?
метапрограммирование спрятано внутри, вы им пользуетесь, просто не знаете об этом.
`v6` — самый подлый, остальные, в принципе, понятно, что получится, хоть и визуальные различия на v2 и v3 реально можно влёгкую пропустить (благо, в большинстве случаев компиляция отвалится дальше, т.к. тип элементов контейнера будет не такой, как ожидалось.
в пример, для ещё лучшего осознания красот двухпараметровой инициализации, можно добавить,
std::vector v7(a, b);
std::vector v8(b, a);
и ещё прикольнее, если тип конструируемой сущности и аргументов конструктора — параметр шаблона типа
template<typename T, typename... ARG>
auto construct(ARG&&... arg)
{
T ret( std::forward<ARG>(arg)...); // (1)
T ret{ std::forward<ARG>(arg)...}; // (2)
// do some processing, registration of `ret` etcreturn ret;
}
Какой вариант правильнее, (1) или (2)? Вроде как (2) кошернее, если там хочешь сужающих преобразований типов избежать, к примеру, ну и вообще, "Uniform" жеж. Но если T — вектор, к примеру, тады ой.
Когда vector виден в коде явно — ещё можно на опыте среагировать на то, что {} может делать не то, что от него ожидал автор. А вот в шаблоне — уже нужно напрячься.
Короче, при всей моей любви к C++, не могу не согласиться, что инициализацию сложно назвать элегантной. Возможно, самое элегантное, что можно было придумать в связи с появлением новых видов инициализации при необходимости иметь обратную совместимость, но от этого элегантности больше не становится.
Здравствуйте, serg_joker, Вы писали:
_>и ещё прикольнее, если тип конструируемой сущности и аргументов конструктора — параметр шаблона типа _>
_>template<typename T, typename... ARG>
_>auto construct(const T&, ARG&&... arg)
_>{
_> T ret( std::forward<ARG>(arg)...); // (1)
_> T ret{ std::forward<ARG>(arg)...}; // (2)
_> // do some processing, registration of `ret` etc
_> return ret;
_>}
_>
_>Какой вариант правильнее, (1) или (2)? Вроде как (2) кошернее, если там хочешь сужающих преобразований типов избежать, к примеру, ну и вообще, "Uniform" жеж. Но если T — вектор, к примеру, тады ой. _>Когда vector виден в коде явно — ещё можно на опыте среагировать на то, что {} может делать не то, что от него ожидал автор. А вот в шаблоне — уже нужно напрячься.
Ну да, это общая проблема использования инит-листов в конструкторах. Я с ней, бывало, сталкивался даже при проектировании собственных классов. С одной стороны, сделали универсальную инициализацию с фигурными скобочками, с другой подсунули эти инит-листы. Мне инит-листы с самого начала не нравились.
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, rg45, Вы писали:
R>Я с ней, бывало, сталкивался даже при проектировании собственных классов.
У меня этот опыт тоже не академический, и мне не понравилось
R>Мне инит-листы с самого начала не нравились.
Да, кроме проблем с правильным выбором перегруженного конструктора, оно ж ещё и копии делает, что как бы не прям очевидно. В тестах штука удобная, в остальных местах обычно получается сделать через другие механизмы, без потери лаконичности и выразительности.
Здравствуйте, serg_joker, Вы писали:
R>>Я с ней, бывало, сталкивался даже при проектировании собственных классов. _>У меня этот опыт тоже не академический, и мне не понравилось
R>>Мне инит-листы с самого начала не нравились. _>Да, кроме проблем с правильным выбором перегруженного конструктора, оно ж ещё и копии делает, что как бы не прям очевидно. В тестах штука удобная, в остальных местах обычно получается сделать через другие механизмы, без потери лаконичности и выразительности.
Ну, кое-какой выход всё-же имеется. Сейчас инициализация с круглыми скобками обладает почти такой же полной силой, как и с фигурными, даже агрегатная инициализация работает. Отсекаются только инит-листы, что мне очень даже подходит. Так что, я в шаблонах использую почти везде круглые скобки. Исключением является только дефолтная инициализация, тут я использую фигурные скобки, чтоб компилер не воспринимал это как объявление функции.
--
Справедливость выше закона. А человечность выше справедливости.