Здравствуйте, B0FEE664, Вы писали:
BFE>Если один и тот же обработчик обрабатывает события от разных кнопок, то ему не важно, от какой конкретно кнопки пришёл вызов.
Это еще почему? Ну и, замени кнопки на textbox'ы, например, и картина точно изменится.
BFE>Если же вызовы различаются, то нет смысла делать один обработчик, чтобы потов внутри различать кнопки.
Есть. DRY называет. Если код обработчиков практически идентичен, то зачем плодить лишние сущности?
BFE>Но даже если вам нужно что-то экзотическое, то вам ничего не мешает под void* положить пару указателей Botton*, OtherData* и дальше работать точно так же.
Я про такую возможность говорил, только это потенциальное усложнение логики каждого обработчика. Не думаю, что оно тут оправдано.
BFE>Но все другие обработчики, добавленные после вызванного, получат вызов для неактивной кнопки, а это нарушение предусловий вызова.
Это вопрос того, какие гарантии предоставляет автор механизма событий. И он совсем обязан гарантировать, что между нажатием на кнопку и вызовом обработчика состояние кнопки не может измениться.
BFE>Только вот при вызове Button::RemoveOnButtonPress() внутри callback'а скорее всего получится segmentation fault или другое UB: ведь в момент вызова callback'а внутри прохода std::for_each будет удалён объект на который указывает текущий итератор.
Это легко обходится через копирование колбэков во временный контейнер и вызов for_each поверх него. Это довольно стандартное решение для ситуаций, когда возможны описки из колбэков.
BFE>Обычно нужен один обработчик на одну кнопку, а если нужно больше, то внутри обработчика уже можно организовать так, как хотите.
Тем не менее, в тех же винформах в .NET там обычный event, на который можно вешать сколько угодно обработчиков. Так явно проще, чем писать кастомные обработчики, раскидывающие события по своим вторичным подписчикам.
BFE>В данном случае ни о какой скорости речи не идёт.