Здравствуйте, smeeld, Вы писали:
S>или при закидывании в массив сохранять индекс, и при удалении сдвигать все эелементы с изменением их индексов
вот в этом кейсе (когда известен индекс) и при условии что порядок элементов не важен, удаление это O(1), надеюсь, хоть немного наморщив мозг, ты найдёшь решение без сдвига элементов
Здравствуйте, smeeld, Вы писали:
S>Здравствуйте, Умака Кумакаки, Вы писали:
УК>>удаление из вектора для данного кейса (когда порядок элементов не важен) это O(1) операция, т.е. не зависит от размера вектора
S>Что ты заливаешь? Удаление из list это O(1), так как там всего лишь перекинуть prev-ы и next-ы. Для удаления из массива нужно или искать его в массиве, причём линейным брутфорсом, а не бинарным поиском, так как не массив неупорядочен, или при закидывании в массив сохранять индекс, и при удалении сдвигать все эелементы с изменением их индексов.
С листе его также искать надо, а собственно удаление найденного элемннта из вектора действительно O(1). Ничего сдвигать не надо.
Здравствуйте, smeeld, Вы писали:
S>Скинь ссыль, где написано, что порядок там неважен?
На интерфейс класса глянь — я там гарантий некоего порядка выполнения хендлеров не вижу. Клиент же не знает, куда его хендлер воткнули и какой он там по счету. Также, удаление неэффективно, так как клиенту никакая инфа о положении его обработчика в списке не отдается
Здравствуйте, Умака Кумакаки, Вы писали:
УК>>>тайпдеф на обработчик события? BFE>>А зачем там передавать указатель на кнопку? УК>чтобы в обработчике событий знать, от кого пришёл ивент
Зачем? К тому же, если эти данные нужны, то их можно положить в то, что скрывается за void*.
УК>>>Тривиальная реализация publish/subscribe? BFE>>Где там publish? УК>функция NotifyAll это publish, AddOnButtonPress — subscribe, RemoveOnButtonPress — unsubscribe
NotifyAll это publish? У меня о publish функциональности несколько другое представление. publish — это то, что можно перечислить внешними методами в неком сторедже. Ну да не важно.
УК>>>Или каррирование частичное применение? Код вообще прозрачный, я в детстве такой писал после пары лет изучения крестов. Учитывая то, что это C++98, на C++17 всё будет выглядеть гораздо лаконичней. BFE>>Прозрачный? Это с void* код прозрачный? И что же скрывается за void*? УК>любой пользовательский контекст.
Вообще-то void* — это нечто прямо противоположное к прозрачному, это полностью скрытые данные или интерфейсы о которых ничего не известно.
УК>Если честно, твои вопросы меня озадачивают, ты вообще сколько кода читал/писал за свою жизнь?
Много. Сотни мегабайтов, наверное.
А вот вы пишите, что это тривиальная реализация. Тогда может объясните, зачем там динамический список обработчиков? Ведь такой список обработчиков имеет смысл только при динамическом изменении этого списка, так как иначе можно просто задать один статический обработчик в котором последовательно и явно в коде написать вызовы всех тех кто хочет быть подписан на эти вызовы. Т.е. один callback в котором просто вписаны вызовы всех других. Если же нужен именно динамический список, тогда может быть вы можете указать на задачу, где у кнопки в рантайме меняется список обработчиков у одной и той же кнопки, причём так, что список этих обработчиков не может быть составлен заранее?
Здравствуйте, andyp, Вы писали:
S>>Как раз для подписчиков порядок может быть очень важен.
A>Из интерфейса класса это никак не следует.
Имя AddOnButtonPress, конечно, не такое выразительное, как push_back, но вполне себе говорит о добавлении.
A>Клиент никакой порядок себе обеспечить не может
Не может обеспечить себе нужный порядок вызова AddOnButtonPress?
Здравствуйте, smeeld, Вы писали:
BFE>>Прозрачный? Это с void* код прозрачный? И что же скрывается за void*? S>Да что угодно. Ты как-будто на C не писал. И в этом его мощь. Если автор не знает, то там скрывается, то ему даже на Go писать нельзя (а то получит ошибку конвертации interface{]-а)
Вот именно. Значит чтобы понять, что там лежит придётся весь код "прошерстить". Если на С void* понятно, то на C++ void* — неуважение к читателю.
Здравствуйте, andyp, Вы писали:
A>Здравствуйте, smeeld, Вы писали:
S>>Скинь ссыль, где написано, что порядок там неважен?
A>На интерфейс класса глянь — я там гарантий некоего порядка выполнения хендлеров не вижу.
А интерфейс класса может служить гарантией чего-то из внутренней его кухни?
Здравствуйте, B0FEE664, Вы писали:
BFE>Зачем? К тому же, если эти данные нужны, то их можно положить в то, что скрывается за void*.
Затем, что во многих ситуациях я хочу оперировать с данными контрола в коллбеке ивента, например сделать кнопку неактивной, получить текст из едитбокса, отписаться от события итд итп. Положить можно в void, только зачем заставлять пользователя библиотеки реализовывать стандартную для любой UI библиотеки машинерию?
BFE>Вообще-то void* — это нечто прямо противоположное к прозрачному, это полностью скрытые данные или интерфейсы о которых ничего не известно.
ты следи за контекстом, прозрачный относилось к коду. И использование void* как пользовательского контекста это вообще практика со времён зарождения си и коллбеков.
УК>>Если честно, твои вопросы меня озадачивают, ты вообще сколько кода читал/писал за свою жизнь? BFE>Много. Сотни мегабайтов, наверное.
А что не гигабайтов? Ты похоже далёк от разработки совсем. Судя по всему, что тебя удивляют стандартные UI паттерны, которые есть в любой UI библиотеке, начиная от MFC и заканчивая HTML DOM с его addEventListener, вероятно ты не настоящий сварщик.
BFE>А вот вы пишите, что это тривиальная реализация. Тогда может объясните, зачем там динамический список обработчиков? Ведь такой список обработчиков имеет смысл только при динамическом изменении этого списка, так как иначе можно просто задать один статический обработчик в котором последовательно и явно в коде написать вызовы всех тех кто хочет быть подписан на эти вызовы. Т.е. один callback в котором просто вписаны вызовы всех других. Если же нужен именно динамический список, тогда может быть вы можете указать на задачу, где у кнопки в рантайме меняется список обработчиков у одной и той же кнопки, причём так, что список этих обработчиков не может быть составлен заранее?
Ты прикалываешься? Это же очевидно UI библиотека, у неё не может быть статических обработчиков, так как они задаются пользователем библиотеки (в рантайме). Боже, какой же ты дремучий.
Здравствуйте, so5team, Вы писали:
BFE>>Многие смогут прочитать и понять, например, это?: S>Сходу не понятно, какой смысл здесь использовать std::list, а не std::vector.
Да? Т.е. зачем может понадобится добавлять динамически (!) несколько обработчиков на одну кнопку вам понятно? Расскажите, зачем?
Здравствуйте, so5team, Вы писали:
S>Имя AddOnButtonPress, конечно, не такое выразительное, как push_back, но вполне себе говорит о добавлении.
Может, оно не такое выразительное как push_front
A>>Клиент никакой порядок себе обеспечить не может S>Не может обеспечить себе нужный порядок вызова AddOnButtonPress?
Не может обеспечить порядок вызова callbacks из контейнера.
Здравствуйте, smeeld, Вы писали:
S>А интерфейс класса может служить гарантией чего-то из внутренней его кухни?
Да. Например, если бы например пользователю было доступно
add_to_front(...) и/или add_to_back(...)
то можно было бы предположить какие-то потуги на соблюдение порядка вызова подсунутых callbacks.
А то что есть сейчас, когда есть только добавлялка и убиралка, именно что никаких гарантий не дает. Наличие внутри коллекции — это вообще деталь реализации.
Здравствуйте, andyp, Вы писали:
S>>Имя AddOnButtonPress, конечно, не такое выразительное, как push_back, но вполне себе говорит о добавлении.
A>Может, оно не такое выразительное как push_front
В жизни, конечно, всякое бывает. Но из того, что мне доводилось видеть, Add обозначает именно добавление в конец.
A>>>Клиент никакой порядок себе обеспечить не может S>>Не может обеспечить себе нужный порядок вызова AddOnButtonPress?
A>Не может обеспечить порядок вызова callbacks из контейнера.
Если добавление идет в конец, callback-и вызываются последовательно, а при удалении хронологический порядок callback-ов сохраняется, то все в порядке.
И да, сам факт вызова callback-ов именно в порядке добавления в интерфейсе вряд ли можно выразить, но это может быть описано в документации.
Здравствуйте, smeeld, Вы писали:
S>По мне, так сложным можно назвать, например, такое
Метапрограммирование, да ещё с макросами, в библиотеке, да ещё в boost — это, конечно, сложный код, который хорошо иллюстрирует мой тезис. Очевидно авторы boost'овских библиотек многое понимают в стандарте C++, но умеют ли они писать на C++? Зависит от автора. Есть такие, чей код сразу можно выкидывать. Вот недавний пример.