Здравствуйте, so5team, Вы писали:
Тё>>>>Ну смотри — удаление подписки. Как ты её собрался искать в контейнере? Какова стоимость?
S>>>Зависит от обстоятельств. К которым мы перейдем ниже, там где фрагменты кода появятся.
Тё>>Не юли.
S>Сперва прочитайте то, что вам пишут, потом уже отвечайте.
OMG да я понял, что вы давно слились, когда запели про "10 подписок".
S>>>Гораздо более серьезно, чем когда вы заявляете, что C++ не используется для рилтайма.
Тё>>Я заявлял, что в ядре не место C++. Именно полноценному C++, ибо C-с-классами не является полноценным C++ в понимании стандарта C++.
S>Вы заявили следующее (http://rsdn.org/forum/job/7907304.1):Автор: Тёмчик
Дата: 17.12.20
Реалтайм бывает soft и hard. Soft вообще похрен на чём делать, а для hard плюсы не подходят (если не рассматривать C с классами).
>> Реалтаймовые системы не на плюсах делают.
S>Все ходы записаны.
Тё>>И часто вас жизнь заставляет замерять оверхед на 10 элементах?
S>Нет. Но бывает.
S>>>Ибо в C++ Node<T> хранил бы экземпляр T не по указателю, а по значению. А то у вас получится по две аллокации на объект в списке: первая для самого T, вторая для Node<T>.
Тё>>Ты в курсе, что есть указатель на T, в данном случае? Может быть, это указатель на какой-то родительский объект или другую подписку, которого можно дёрнуть для оповещения об изменениях. Может быть, его и заполнять необязательно.
S>Тёмчик, давайте говорить о примере от B0FEE664. В котором под T можно подразумевать только std::pair<OnPress, void*>. Если вы хотите ввести в обсуждение еще что-то, то потрудитесь это описать, чтобы люди понимали, о чем речь.
Почему у вас onpress в типе? Почему у вас void*? Вы что, про статическую типизацию не слыхали?
По уму, там интерфейс нужен типа такого
interface Subscriber<T> {
void accept(T const &arg);
}
Тё>>Чувачелло, величина твоего невежества зашкаливает. Но я же привёл ссылку. Сложно прочитать?
Тё>>Тё>>>>https://en.wikipedia.org/wiki/Sentinel_node#Linked_list_implementation
S>Т.е. вы для хранения списка подписок предлагаете хранить еще и специальный sentinel node?
Я не "предлагаю" — это оптимизация связного списка для упрощения его операций, почитайте, учиться ведь всегда полезно.
Тё>>Если пописчиков немного, то не стоит заморачиваться на алгоритмическую сложность.
S>Если вы еще не заметили, то речь идет не про алгоритмическую сложность, а о стоимости по памяти и времени исполнения. В случаях, когда подписчиков немного.
Тё>>Кто управляет временем жизни callback?
S>Подписчик.
Ну вот ваш подписчик должен хранить интерфейс для отписки. Может хранить пачку таких подписок в списке, и отписываться в деструкторе, например. Тоже такой наивный способ. Элегантный способ в
http://reactivex.io/ — использовать оператор takeUntil().
S>>>Если достаточно всего лишь указателя на callback, то хранение для каждой подписки Subscription -- это дополнительная головная боль. Особенно в C++, где ничего не защищает от обращения к повисшим указателям.
Тё>>У хорошего плюсника не бывает тухлых указателей. Вы к таким определённо не относитесь.
S>Без разницы к каким вы меня относите. Суть в том, что такая проблема есть. И решений, которые ее провоцируют, следует избегать. Тогда будет не важно, хороший плюсник работает с кодом или нет.
S>>> Использовали экземпляр subscription для отписки один раз, а потом, по ошибке, сделали отписку повторно. И что будет в итоге?
Тё>>В итоге будет nullptr и это правильно. Ибо кривые руки повторно-вызывальщиков отписок, релизов, диспозов и прочих делетов нужно испрямнять жёстко и без церемоний.
S>На словах все герои. Только вот если у вас отписка работает через поиск (по указателю на callback или по какому-то уникальному Id), то она оказывается более устойчивой к подобным ошибкам.
Т.е. вы смирились с фактом, что в вашем говнокоде нет определённости, придёт отписка дважды, или вообще не придёт. И поэтому вы городите тормозной кривой код, оправдывая это порно "локальным кэшем".
S>Кроме того, в C++ объекты по умолчанию копируются. Т.е. если есть:
S>S>class Subscription {
S> Node * node_;
S>public:
S> ...
S> void unsubscribe() {
S> if(node_) {
S> ...
S> node_ = nullptr;
S> }
S> }
S>};
S>
S>То потребуется еще позаботится о том, чтобы объекты Subscription не копировались. Потому что зануление node_ в копии никак не скажется на исходном объекте. А до C++11 нормальных средств для этого в языке не было (а код от B0FEE664 явно написан для C++98).
Возвращается ссылка на интерфейс Subscription. Это может быть наследник от Node имплементирующий Subscription. О каком каком копировании вы поёте?