Re[11]: Concept-Based Polymorphism
От: B0FEE664  
Дата: 17.07.20 21:10
Оценка:
Здравствуйте, 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 — параметрический полиморфизм.
И каждый день — без права на ошибку...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.