Здравствуйте, so5team, Вы писали:
S>>>А std::function с лямбдами в C++ можно рассматривать как сахар для классов вроде ProviderCaller/CallerForProviderOne/CallerForProviderTwo.
BFE>>Есть принципиальная разница состоящая в том, что ConsumerOne и ConsumerTwo ничего не знают о ProviderCaller.
S>Зато они вынуждены знать про std::function<void()>. Тоже самое, что и знать про ProviderCaller с operator()
Нет, не тоже самое. От std::function<void()> никто не наследуется.
BFE>>Это не просто сахар, это принципиально другой вид отношений между классами.
S>Пока не видно почему.
Взгляните на архитектуру примеров. У них разная архитектура.
BFE>>В случае использования Signals-slots классы можно переименовывать и менять независимо друг от друга, а в приведённом примере изменения названия ProviderCaller, скажем на ProxyCaller приведёт к редактированию аж 4-х классов!
S>Тоже самое произойдет если вы решите заменить std::function на какой-нибудь my_fast_delegate.
Нет конечно. В ConsumerOne можно заменить
std::function на какой-нибудь
my_fast_delegate, а в ConsumerTwo оставить как есть.
S>Ну и, как уже было сказано, в случае с лямбдами у вас есть сахар со стороны компилятора, который автоматически делает классы, который мне пришлось выписывать руками.
Не согласен. В
std::function есть стиратель типа, а у вас его нет. Вот если бы вы предложили заменить std::function указателем на функцию, тогда можно было бы согласится.
S>Но с точки зрения типа применяющегося здесь полиморфизма разницы нет.
Т.е. вы хотите поговорить об
определениях.
Существует несколько разновидностей полиморфизма. Две принципиально различных из них были описаны Кристофером Стрэчи[en] в 1967 году: это параметрический полиморфизм[⇨] и ad-hoc-полиморфизм[⇨], причём первая является истинной формой, а вторая — мнимой[1][4]; прочие формы являются их подвидами или сочетаниями.
Ну так какой это полиморфизм?
BFE>>Есть и другое отличие.
BFE>>Если вам нужно будет добавить провайдера для второй функции (с такой же сигнатурой):
BFE>>BFE>>class ConsumerOne
BFE>>{
BFE>> public:
BFE>> ProviderCaller& provider_1;
BFE>> ProviderCaller& provider_2;
BFE>> void g() { provider_1(); }
BFE>> void h() { provider_2(); }
BFE>>};
BFE>>
BFE>>то как вы будете это реализовывать в CallerForProviderOne ?
S>Не понятно, при чем здесь CallerForProviderOne?
Ну а как ? Заведёте ещё CallerForProviderThree? И так для каждого нового метода?
BFE>>Ещё одно отличие в том, что для Signals-slots использование виртуальных функций не обязательно.
S>Напомню, что речь шла о различиях между статическим и параметрическим полиморфизмом. Точнее в выяснении того, что вы под этим понимаете.
Ну раз вам так интересно, что подразумеваю я (быть может не правильно), то вот:
В случае использования шаблонных параметров — статический полиморфизм.
В случае использования виртуальных функций — динамический полиморфизм.
В случае использования type eraser — параметрический полиморфизм.