Pull to refresh
15
0
Владислав Навроцкий@navrocky

Пользователь

Send message

В креаторе уже есть зачаточная поддержка разработки в докере, аналог дев контейнеров. Год назад я это щупал. Не знаю насколько продвинулись в этом направлении.. Если допилят до состояния как в VSCode, тогда можно будет не изобретать такое.

Надеюсь в следующих частях увидеть как для этой библиотеки настроить пайплайн на github, со сборкой релизов и публикацией в conan. По мне это одна из самых главных фишек библиотек, если она есть в package менеджерах - её будут использовать намного чаще.

Я после долгих лет использования различных сервис локаторов от ВАУ какая штука пришел к пониманию что лучше жить без них. Основная проблема в сервис локаторах заключается в том, что мы перекладываем проверку корректности конфигурирования зависимостей нашего приложения на рантайм. Если по старинке создавать все объекты в образном main и передавать им все зависимости в конструкторе, то проверкой, всё ли мы передали, будет заниматься компилятор. И не будет ситуации, когда работающее приложение в какой-то момент вылетает, потому что lazy зависимость не удовлетворена.

И не нужны никакие библиотеки. Если нужен синглтон - передаешь в конструктор созданную зависимость, если нужна фабрика, передаёшь в конструктор функцию создания.

Ещё есть ncdu(https://linux.die.net/man/1/ncdu) которая присутствует во многих дистрибутивах.

Не совсем понял к чему тут объяснение что такое лямбда? Причем, у вас пример не правильный, не хватает [] в начале.

синтаксический сахар сделает это за вас.

Какой синтаксический сахар? Синтаксис лямбды в C++ сложно назвать сахаром 😅

Чукча писатель, не читатель. Полагаю откуда-то копипастилось не глядя, и html эскепинг просочился

В вашем комментарии речь шла о чейн функциях, в моем примере они есть. Не понимаю в чем вы видите различие вызов через точку или вызов через | ? Семантически это одно и то же. И да лямбды в плюсах уродливые, тут ничего с этим не сделаешь.

И в плюсах оператор точку не то чтобы нежелательно, её нельзя перегрузить для чужого класса.

Так я же привёл пример реализации функции transform, это как раз и есть прямой аналог let в Kotlin. Остальные функции можно сделать по аналогии.

11 | transform([&](auto v){ return (std::stringstream() << v).str(); })

И я надеюсь, что компилятор это способен оптимизировать до простых вызовов.

О, я даже и не знал что такой оператор есть ) Да, синтаксис вызова неудобный, не подойдёт

ниеблоидом

Сперва подумал что это что-то на матерном ) Почитаю про это )

Но я просто хотел показать как проэмулировать методы расширения. Ranges прикручивать не каждому надо, и заниматься высшей магией с ниеблоидами.

Использование функций для этого не совсем кошерно, можно использовать constexpr переменные, дабы получить более вкусный синтаксис. Условно (value->as_int) навариваем сюда концептов и получаем забавный способ что-то сделать

Я думал о глобальных константах вместо функций. Но есть функции с параметрами, их constexpr переменными не сделаешь.

Ну я это не в библиотеке использую, а в своём проекте. В библиотеке я, наверное бы, не стал навязывать такие интерфейсы.

Да можно. Но опять таки это только про работу над списками. А хочется применить не только для списков. Надо попробовать старые ranges затащить в мой C++17 проект, вроде сторонних зависимостей нет

Ну вот патчить компилятор это вообще последнее дело

О даааа =)

Жалко что нельзя свои операторы определять, вот тогда бы вообще раздолье было бы )

Кстати в Котлин есть инфиксные функции, наверное и в других каких-то языках есть тоже. Можно делать так:

infix fun <A, B, C> then(a: A, b: T): C { TODO() }

// и потом писать такое
1 then "lala" then false

Да в плюсах с лямбдами туго, мне тоже не хватает упрощённого синтаксиса.

var names = string.Join(", ", personList.Where(p => p.age < 30).Select(p => p.name));

В С# (кажется это он) ещё не очень лаконично. Вот то же на Котлине, вот где красота:

val names = personList.filter { it.age < 30 }.map { it.name }.joinToString(",")

Это значит, что какая-то библиотечная функция уже вернула вам объект, например строку std::string, которую она создала. И тут у вас есть только возможность обернуть возвращённую строку в вашу строку с дополнительным методом.

Да в C# самая корявая реализация, но это было первое что я увидел в 2012. А так да UFCS то что надо. В Kotlin мне, например, нравится явность определения функции как метода:

// обычная функция
fun <T> first(list: List<T>) = list[0]

// метод - расширение
fun <T> List<T>.first() = this[0]

Кстати Wikipedia говорит, что

This has again, in 2023, been proposed by Herb Sutter[13] claiming new information and insights as well as an experimental implementation in the cppfront compiler.

Возможно мы в каком-то стандарте и увидим такой синтаксический сахар, может и доживём.

Фактически вы просто использовали другой оператор для того, что уже давно и так известно и широко применяется -- перегрузка операторов << и >>

Да, я перегрузил | по аналогии с библиотекой ranges, хотя можно было перегрузить и оператор >>, было бы нагляднее.

items >> map() >> filter() >> collect()

К сожалению оператор -> и . нельзя перегрузить вне класса. Да и это бы вносило путаницу с указателями.

Это ведь и есть те самые "методы расширения".

Да, но в стандартной библиотеке это применимо только к потокам. Я просто обобщил. Ну и флоу тут "обратный" потокам.

Ну потратил он один раз 5 минут разобрался и дальше проблем не возникает. Мне этот поход зашел в одном реальном проекте, ranges я не могу использовать потому я ограничен C++17, а цепочечные преобразования очень хочется, так как надоело писать постоянно императивные for. Я наклепал по быстрому различные функции над коллекциями, mapToVector, toSet, toVector, joinToString, reduce и теперь пишу однострочники в стиле ranges:

auto names = personList | filter([](auto p){return p.age < 30;}) | 
    map([](auto p){return p.name;}) | joinToString(", ");

Второе где пригодилось это при сериализации моделек данных в Json, мой последний пример. Я сперва пробовал сыграть на перегрузке функции toJson для разных типов, но в итоге столкнулся в шаблонном коде с тем, что компилятор довольно мудрёно ищет подходящие перегрузки и словил кучу проблем с неймспейсами и позицией в коде что первее чего объявлено. Переписал toJson на такой "метод расширения" и всё теперь работает просто и понятно, достаточно перегрузить оператор для нужного типа. Также можно писать конвертеры, например toDto, toModel:

person | toDto();
// или
personDto | toModel();

Information

Rating
Does not participate
Location
Ростов-на-Дону, Ростовская обл., Россия
Date of birth
Registered
Activity

Specialization

Specialist
Ведущий
Kotlin Multiplatform
TypeScript