- 1
page < records.total_pages ? next_page_exist = true : next_page_exist = false
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
+2
page < records.total_pages ? next_page_exist = true : next_page_exist = false
очевидное должно быть очевидны
чувак
next_page_exist = (page < records.total_pages)
Вообще я бы написал вот так (недавно узнал про лямбды):
В некотором смысле тут есть и паттерн "стратегия", потому что логика инкапуслирована в класс.
Мой вариант тренарника:
Такие конструкторы лучше делать constexpr T() noexcept (если все инициализаторы членов соответствуют), чтобы можно было безболезненно наследовать constexpr-классы.
> bool next_page_exists() const noexcept
> operator bool() const noexcept
page() и total_pages() не объявлены как noexcept, поэтому лучше noexcept убрать (иначе залётное исключение из page() мгновенно убьёт весь процесс).
> ~my_useful_class_impl() override = default;
Это можно не писать, неявные деструкторы классов-наследников виртуальные по умолчанию (если у класса-предка есть виртуальный деструктор).
> foo.insert(foo.begin(), 1);
foo.push_back() сначала 2, потом 1?
std::vector<int> foo = { 1, 2, /* 3 */ /* Uncomment to make true */ }; ?
std::vector<int> foo { 1, 2, /* 3 */ /* Uncomment to make true */ }; ?
Спасибо.
>constexpr
всё время забываю(
>е объявлены как noexcept
надо бы объявить. Хотя я не уверен на счет гарантий у размера у вектора
>неявные деструкторы классов-наследников виртуальные по умолчанию
Я не настоящий крестовик, так что мне спокойнее всё писать явно: удалять все ненужные конструкторы и объявлять все нужные деструкторы.. Хотя наверное хря
>сначала 2, потом 1?
ну это разве важно?:)
> std::vector<int> foo = { 1, 2, /* 3 */ /* Uncomment to make true */ }; ?
да, с инициализатором расивее, спасибо
По стандарту noexcept там, не сцы. Да и интуитивно size() -- это просто число или разность джвух указателей. Нечему бросать исключения.
В следующей версии своего объектно-ориентированного фреймворка для создания тренарников обязательно так сделаю. В платной версии
Это полезно, но для базовых классов/интерфейсов noexcept — очень "сильный" модификатор, его нужно ставить с осторожностью. С ним наследники должны в обязательном порядке ловить и обрабатывать, например, std::bad_alloc на каждой аллокации (стандартных контейнеров, std::make_***(), ...), а это далеко не всегда удобно.
В общем можно просто сдохнуть при bad_alloc?
А что будет, если я обману: скажу noexcept, а кину bad_alloc?
Какой=то десктруктор может не вызваться?
В гугловском кодестайле так и предлагается, насколько я помню. Упало -- да и хуй с ним.
Но в общем случае каким-то проектам нужно переживать временное out of memory.
Я это и назвал "строишь логику в зависимости от доступности свободной памяти".
Это сильное колдунство кмк:)
заебали переизобретать пхп
Поля хороший пример привела с вебсервером. Жабаёбы тоже примерно так делают: ловить NPE например вообще-то не нужно обычно, но если ты контейнер сервлетов то можно и поймать, и вернуть 500.
Никакой не вызовется, емнип. Будет сразу std::terminate.
Но если я не делаю что-то для "внешнего кода", "для сторонних разработчиков" то наверное я не должен ловить bad_alloc .
Если конечно я не пытаюсь как-то "переживать временное out of memory", как говорил Борманд
Нужно чтобы каждый плагин жил в своем процессе и работал по IPC.
Словил сегфолт? Мне похуй.
Пытаешься передать структуру с левыми ссылками? Мне похуй, у меня свой address space.
Конфликт зависимостей? Мне похуй, вот тебе отдельный процесс, впендюривай туда какие хочешь версии библиотек и никакой хуйни с конфликтами плагинов.
Выжрал памяти? Мне похуй, а еще мне issues не будут засирать что это моя платформа видите ли много жрет.
В целом конечно ты прав (и тред такой есть), но IPC не бесплатен. В чужое адресное пространство ходить (не через шаред мемори а через сокеты/пайпы) это МОЖЕТ БЫТЬ медленно.
Там еще когда-то language server для иде хотели реализовывать, эх.
Ну вот выселил ты клиента СУБД в отдельный процесс и общаешься с ним асинхронными месседжами. Заебись же!
Но тут он взял, да и помер. И какой толк от всего остального приложения, если оно даже в СУБД писнуть не может?
В целом же снова посылаю тебя к блеску и нищете микроядер, харда и пр:)
А в целом если основное приложение знает какие у него плагины, то просто перезапускает процесс и не течет
В тред приглашается Снаут с рассказом про акторы в эрланге
но вообще есть еще кое-какая беда, конечно. плагин может взрываться хоть каждые пять минут, а конечный юзер будет охуевать почему у него то есть кнопка, то нет.
Передаю слово: https://www.youtube.com/watch?v=HyiSYHfESX4 (мотайте на 17:55) Там в общих чертах говорится про акторы и let it crash.
Клиент субд в отдельномых процессеах используется сплошь и рядом. Если клиент покрашится, в простейшем случае он тупо утянет за собой процесс, который его использует, через link, web-server, создавший процесс, это задетектит и вернёт 500.
ма-те-ма-ти-ком?
Ну ребутнётся, делов то. Супервизор же у него какой-то есть. Да и репликацию никто не отменял.
Если это поможет. А если он не поднимица обратно?
>репликацию
Это можно, но это нужно делать. Упал питеху, другой поднял его знамя
Проблемы пхпшника, нарисовавшего плагин + exponential backoff на попытки поднять
О, даешь кодогенерацию на языке программирования «systemd service». Серьезно, пуусть качает плагин по имени, засовывает его системд-сервисом в .config/systemd/user/ и вообще ничего не знает про проблемы супервизора. Нужно отключить плагин? Выключил сервис системд да и делов.
Кстати, systemd еще и сокет умеет за тебя сделать. Скоро в ядро systemd еще и интеграцию с твиттером прикрутят. Сейчас systemd не работает без dbus, а скоро без аккаунта в твиттере рабоатть не будет
Милениалы в конце концов изобретут DCOM. Так им и надо
Это правильно. Опытные крестовички (ударение по ситуации) знают, что у базового класса обязательно надо удалять дефолтные конструкторы копирования/перемещения, иначе потом кто-нибудь скопирует объект через ссылку на родителя и получит огрызок объекта.
> ну это разве важно?:)
Не знаю, я не вникала, на кой ляд тебе эта эмуляция push_front(...) через insert(begin(), ...) сдалась, но я в чужие дела не лезу, хочешь вставлять в начало, значит есть зачем.
Алсо, я не понимаю как наследник A может дать или не дать свое согласие на копирование
Куда говорит его хранить аллокатор. Аллокатор по умолчанию в С++ выделяет память оператором new.
> на что указывает z_ptr
На вновь созданный объект. Фактически это было бы эквивалентно
А* z_ptr = new typeid(*x_ptr)(*x_ptr);
если бы так можно было делать.
Объявить clone можно было бы как
* узнать через RTTI какой это объект
* создать в куче этот объект и вызвать у него копирующий коснтруктор, передав туда A, скащенный в нужный объект?
Звучит логично, но не очень понятно что делать, если объект (или один из его предков) копирования не позволяет
Алсо, а поинтер на кучу будет какой? Умный, або обычный? In the latter case его нужно явно delete потом?
В духе остальной стандартной библиотеки — кидать исключение.
> Алсо, а поинтер на кучу будет какой? Умный, або обычный?
В идеале, сделать перегрузки для всех стандартных указателей. Какой засунул — такой и получил. В крайнем случае, полученный сами обернут, чтобы вручную не удалять.
Хотя всем остальным видам new нужно явно указывать тип. Не подходит.
Рубисты любят лямбды и даже по массиву итерируются блоком.
Правда явно выбирать что и как захватывать вроде бы можно только в крестах (и еще в одном помоечном языке, который я не знаю)
Полный код: https://wandbox.org/permlink/vmVy2nsvDAkcUjeI
Пил с Полиной молочко,
А теперь болит <_ _ _ _>.
Отгадка:
https://otvet.mail.ru/question/198958680
@
if a not == 42: ...
@
traceback (most recent call last):...
@
недовольно урчиш
В MRI давеча джита завезли. Теперь поди и змеюка у него отсасывает