Chaos_Optima
> она у тебя не работает.
> mData = (const MyData&) getData(); // ты знаешь сигнатуру getData() а если тут
> robot.getData = Connector(world, &World::AboutUnit); World::AboutUnit это
> World::AboutUnit(int,float,string) то у тебя ничего не будет работать.
Chaos_Optima
> эм.. а каким образом робот тогда будет вызывать этот метод? Он в любом случае
> должен знать сигнатуру.
Chaos_Optima
> так ты сам себе противоречишь. любишь строгость, но при этом делегат у тебя
> принимает любой метод, но вызывает исключительно если сигнатура совпадает, где
> логика?
Chaos_Optima
> самое забавное что твой метод будет работать с большими костылями когда метст
> вызова будет много и мест привязки будет много, а если ещё добавить
> многопоточность то вообще вилы.
Chaos_Optima
> не способен, он вообще не является по сути делегатом. Делегат должен быть по
> сути как функция, то есть поддерживать неявный каст, реагировать на
> неправильные аргументы (при вызове и при привязке) во время компиляции, твой
> коннектор не отвечает ни одному из требований.
Задача делегата - уметь нацеливаться и запускать удаленные функции.
Быть "по сути как функция, на которую он нацеливается" - это большой плюс, но не является определением коннектора.
p.s.
Kartonagnick
> if(con.CanLaunch(10)) con(10); //робот понятия не имеет, какая там снаружи
> сигнатура. Ему наплевать.
Искусственный интелект шагает по планете :D :D
Grey304
> Функтор Chaos'а до такой возможности допиливается элементарно.
Я понял ваше заменчание. Единственное: по уму, оно не должно "допиливаться", оно должно "уметь работать".
Раньше, я думал о возможной поддержке смартов. Но в последствии отказался. Потому что 2003 стандарт, и полное отсутствие самих этих смартов.
Но тогда мне просто в голову не пришло, что можно работать не с типом класса, как таковым (определять правомерность цели не по типу самой цели), а по её строению.
(вот опять понадобился глубокий анализ типа. Интересно, как "идеальный" делегат Хаоса нацеливается не зная, на что он нацеливается то? )
Меня заинтересовало ваше замечание. Я готов реализовать вот такую возможность:
Grey304
> Искусственный интелект шагает по планете :D :D
Робот не думает о том, какие типы нужны кому то там снаружи. Он вообще ничего не знает о среде. Но он знает, что согласно собственной бизнес-логике, при достяжению некоторого внутреннего состояние он должен излучить сигнал куда то в эфир. Куда, зачем, почему, кто и как будет улавливать этот сигнал - роботу безразлично.
if(con.CanLaunch( 10)) con( 10);
Если я могу излучить сигнал 10 по данному коннектору, то я излучаю этот сигнал.
Ну и нахрена роботу знать о том, какие где то там снаружи сигнатуры?
Kartonagnick
> В первом случае, робот оснащен всеми необходимыми инструкциями на случай
> нерабочий связи, на землю ему наплевать.
> Во втором случае, о любых неисправностях я узнаю через мгновение сразу, после
> запуска тестов.
ты не понимаешь? в случае function ему также плевать на землю. И при этом все неисправности детектируются на этапе компиляции!
В твоём случае как минимум необходимо писать тест, а вдруг тест ты не написал, и вызывается она у тебя раз в сутки допустим, это же ппц.
Kartonagnick
> Нет никаких методов. Нет никакой земли. Нет никакой среды. Ничего этого
> НЕ-СУ-ЩЕ-СТВУ-ЕТ.
> Дошло наконец?
facepalm да нету, но сигнатуру он в любом случае должен знать чтобы вызвать делегат! до тебя ДОШЛО?
Kartonagnick
> Он посылает сигнал: число 10, а уж какие там сигнатуры, куда оно там попадет, и
> можно ли вообще отправить такой сигнал по данному коннектору - да пофиг вообще.
как пофиг? у тебя же асерт вызывается, было бы пофиг асерт бы не вызывался. И дело даже не в этом. представь ты привязываешь функцию и надеешься что её вызовут но она не вызывается, потомучто ты написал не const char* а string вот тут и начинается беда с поиском места вызова.
Kartonagnick
> Можно рассматривать, как эквивалентные записи. В первом случае отсутствует
> протокол. поскольку вся сигнатура вытряхивается из самой функции.
нет нельзя, во втором случае неправильный вызов или присваивание будет детектится в compile time и работать будет быстрее.
Kartonagnick
> Костыльная архитектура и многопоточность ортогональны к теме делегатов.
да неужели? GUI никогда не писал?
Kartonagnick
> - это большой плюс, но не является определением коннектора.
нет. это является определением делегата
Chaos_Optima
> ты не понимаешь? в случае function ему также плевать на землю. И при этом все
> неисправности детектируются на этапе компиляции!
> В твоём случае как минимум необходимо писать тест, а вдруг тест ты не написал,
> и вызывается она у тебя раз в сутки допустим, это же ппц.
Понятно, что ошибки времени компиляции предпочтительнее, чем ошибки времени выполнения.
А тесты в любом случае нужно писать. "Любой новый код всегда содержит ошибки"(ц)Босс.
Если конечно, тебе нужны гарантии стабильности приложения.
И это ортогонально к теме делегатов. 99,9% ошибок, судя по моему опыту - ошибки в бизнес-логике. А не в механизмах связки.
И я заколебался писать об этом уже в 10й раз.
Chaos_Optima
> facepalm да нету, но сигнатуру он в любом случае должен знать чтобы вызвать
> делегат! до тебя ДОШЛО?
Chaos_Optima
> как пофиг? у тебя же асерт вызывается, было бы пофиг асерт бы не вызывался. И
> дело даже не в этом. представь ты привязываешь функцию и надеешься что её
> вызовут но она не вызывается, потомучто ты написал не const char* а string вот
> тут и начинается беда с поиском места вызова.
Chaos_Optima
> нет нельзя, во втором случае неправильный вызов или присваивание будет
> детектится в compile time и работать будет быстрее.
Нужно замерить скорость в релизе.
Chaos_Optima
> да неужели? GUI никогда не писал?
Chaos_Optima
> нет. это является определением делегата
Определение делегата: механизм, способный делегировать задачи одних механизмов другим механизмам.
В контексте сабжа: делегировать задачи одной сущности другой, в условиях когда они ничего друг о друге не знают.
Как именно они это делают, и как проверяют возможные ошибки и прочее - это детали реализации, а не определение самого понятия делегата.
Руль - деталь реализации, а не определение автомобиля.
Kartonagnick
> Робот не думает о том, какие типы нужны кому то там снаружи. Он вообще ничего
> не знает о среде.
Вопрос на засыпку.
class Robot { public: void setHandler(Den::Connector handler); };
Как пользователю этого класса узнать, какую функцию туда можно положить, а какую - нет?
При применении нормальных типизированных функторов код получится самодокументируемый..
Kartonagnick
> Интересно, как "идеальный" делегат Хаоса нацеливается не зная, на что он
> нацеливается то? )
Kartonagnick
> А тесты в любом случае нужно писать.
не всегда и не везде можно обеспечить полное покрытие кода.
Kartonagnick
> Блин, да ничего он не должен! Он излучает сигнал, если может. И не излучает,
> если не может. Точка.
> Проблемы 1й точки шерифа 2й точки не ипут.
ты не догоняешь? у тебя там асерт вызывается при неправильном обращении, а это значит что он должен знать сигнатуру, хотя бы 1 из них. А тот кто привязывает, должен вообще знать точную сигнатуру.
Kartonagnick
> Если коннектор работает в режиме "без проверок", то предполагается, что связь
> всегда должна быть корректная.
ты же понимаешь что вызов у тебя очень строгий? причём строгий не во время компиляции, а строгий во время исполнения. что является крайне неудобным.
И проверки у тебя на месте вызова, а не на месте привязки. Как ты вообще сможешь узнать где ошибка?
Kartonagnick
> Нужно замерить скорость в релизе.
да без разницы, у тебя проверки аргументов в динамике через typeId, а это в любом случае будет медленнее работать.
Kartonagnick
> Писал. Именно поэтому я и говорю - тема делегатов ортогональна теме костыльной
> архитектуры.
а причём тут костыльная архитектура?
Kartonagnick
> Слышал когда нибудь о противниках goto? Они считают, что оператор goto может
> превратить код в спаггети.
не в спагети, это тут не причём, goto делает прыжки, которые читать крайне неудобно, что соответственно затрудняет поиск ошибок, поэтому его и не рекомендуют использовать.
Kartonagnick
> А в педальной эвент-систем, что мне довелось несчастье столкнутся однажды,
> очень нереально было понять: а где вообще!? Искать все эти 1е точки.
> Там сам черт ногу сломит. Делегаты педалят делегатам по длинющей петле то и
> дело ныряя во всякий буст, да ещё и в рекурсии.
это абсолютно верно для твоих делегатов, но для всех остальных всё нормально. Все точки находятся очень просто, их можно отдебажить, т.к. они всегда вызываются, потому что в нормальных языках сигнатура должна совпадать.
Kartonagnick
> Вот только какое это имеет отношение к моему коннектору?
эм... дело в том что то что ты сказал, относится исключительно к твоему коннектору, а вот к нормальным делегатам не относится.
Grey304
> Вопрос на засыпку.
Kartonagnick
> Это должен знать программист 1 точки. Его задача - связать компоненты. Для
> этого он должен знать о том, кого связывает.
> Ему нужно понимать какие данные нужны роботу, и знать какой именно метод
> предоставляет нужные данных от поставщика
ну так получается ты не освобождаешь его от знания сигнатуры, и даже не подсказываешь её ему.
Kartonagnick
> Как в таком самодокументируемом коде программист узнает, какой именно коннектор
> хочет робот?
эм... это же очевидно, тот у которого сигнатура int()
Kartonagnick
> //<--- автоматический выбор нужной перегрузки,
> //согласно протоколу данных, требуемых терминатору
прикинь в function и у меня выбор осуществляется автоматически.
Kartonagnick
> Это должен знать программист 1 точки. Его задача - связать компоненты. Для
> этого он должен знать о том, кого связывает.
> Ему нужно понимать какие данные нужны роботу, и знать какой именно метод
> предоставляет нужные данных от поставщика
Просмотрев весь код класса Robot?
Kartonagnick
> Как в таком самодокументируемом коде программист узнает, какой именно коннектор
> хочет робот?
А это, как вы выражаетесь, не задача Робота.
Он предоставляет возможность - и его не волнует, дадут ему GetData1 или GetData2.
Зато пользователю ясно, что если он хочет давать Роботу данные - то ему нужен метод, возвращающий int.
Kartonagnick
> Можно рассмотреть вот такой случай:
Если проблема в перегруженных функциях - static_cast в зубы и вперед:
Chaos_Optima
> эм... дело в том что то что ты сказал, относится исключительно к твоему
> коннектору, а вот к нормальным делегатам не относится.
Странно. Потому что эту проблему я наблюдал в проекте, в котором не использовался мой коннектор. Там использовался std::function со всякими буст-биндами и ещё воз и малая тележка всякого маловразумительного добра.
Chaos_Optima
> эм... это же очевидно, тот у которого сигнатура int()
Chaos_Optima
> прикинь в function и у меня выбор осуществляется автоматически.
Все вопросы связанные с перегрузками решает TConnector
Chaos_Optima
> ну так получается ты не освобождаешь его от знания сигнатуры, и даже не
> подсказываешь её ему.
Ты никак его не освободишь от необходимости знать и о поставщике и о потребителе. Не просто о сигнатурах, а о самих механизмах. О том что и как они делают.
Программисту 1й точки нужно совершенно четко осознавать какие услуги он определяет для потребителей.
Grey304
> Просмотрев весь код класса Robot?
Неет. Просмотрев документацию робота. И поняв что за данные он принимает.
С поставщиками аналогично.
Grey304
> А это, как вы выражаетесь, не задача Робота.
> Он предоставляет возможность - и его не волнует, дадут ему GetData1 или
> GetData2.
> Зато пользователю ясно, что если он хочет давать Роботу данные - то ему нужен
> метод, возвращающий int.
Grey304
> Ублюдочно, но так ли часто надо подписывать перегруженные функции?
> Ну а функтору Chaos'а так и подсказки не надо давать))
Тема в архиве.