Нет, типы знать не нужно. Шаблоном не будет :). Ну то есть будет, но параметры — не итераторы, а тип значения и категория.
Как-то так это можно сделать: https://pastebin.com/Z6wemSjB
git clone https://github.com/AlexKiryushkin/rttg
cd rttg/examples
mkdir build && cd build && cmake ..
make
rttg/include/rttg/impl/invoke.h:59:54: error: call to object of type 'rttg::Overloader<(lambda at /Users/izvolov/prog/src/rttg/examples/access_individual_element.cpp:13:18),
rttg::detail::FallbackEmptyCallable<false> >' is ambiguous
[&compositeCallable](auto && value) { return compositeCallable(value.get()); },
^~~~~~~~~~~~~~~~~
В данном случае речь идёт о том, что итератор определяет обход последовательности и выдачу элементов.
При этом итератор не знает, что будут делать с выданными им элементами: умножать, складывать, что-то ещё.
Из проблем, навскидку:
Неочевидные просадки по производительности в простых случаях (например, если поставить filter после transform, который читает из файла или делает что-то долгое). При этом код корректен, компилируется и работает.
Накладные расходы на хранение данных в сложных итераторах (например, чтобы решить предыдущую проблему, можно создать итератор, который будет кэшировать промежуточные вычисления. Но чтобы это засунуть в итератор, потребуется завернуть кэш во что-то типа shared_ptr, а это уже лишний уровень косвенности.
std::function, Boost.TypeErasure, Boost.Polycollection
Во, вот это правильная реализация.
Как делается настоящее стирание типа без виртуальной шляпы — см.
std::function
.Более продвинуто — Boost.TypeErasure.
А за виртуальный метод
clone
в плюсах полагается расстрел на месте.Так и не понял, в чём элегантность и "расширяемость" по сравнению, к примеру, с вариантом:
Как говорится, нет такого преступления, на которое не пойдут джависты, даже под страхом виселицы, лишь бы обмазаться 300% паттернов.
https://ru.wikipedia.org/wiki/«O»большое_и«o»_малое
Программисты на Свифте профильной литературы не читают и в
школеинституте не учатся?Зачем обыкновенное О-большое называть "Big O"?
Интересно. Похоже на Boost.TypeErasure.
Извините, сорвалось.
У вас ус отклеился.
По сути: дико запутанно и неудобно. Непонятно, кто и зачем будет пользоваться этой мешаниной.
Нет, типы знать не нужно. Шаблоном не будет :). Ну то есть будет, но параметры — не итераторы, а тип значения и категория.
Как-то так это можно сделать: https://pastebin.com/Z6wemSjB
Без виртуальных функций можно делать через механизм обобщённых обработчиков. Писал об этом тут: https://habr.com/ru/post/302372/#manager
Или можно посмотреть реализацию std::function в любой современной стандартной библиотеке.
Предварительные результаты замеров в попугаях:
Обычные итераторы: 26
boost::any_iterator: 215
variant_iterator (самописный): 32
Также эксперементирую самописным any_iterator без виртуальных фунций, но быстрее пока не выходит.
Справедливо. Надо бы замерить.
https://habr.com/ru/post/490850/
См. раздел "Нужно больше предупреждений".
Под множеством, как я говорил, тут подразумевается отсортированный диапазон. Если элементы повторяются, то это "мультимножество".
Компилятор clang, макось.
Спасибо!
Сейчас, к сожалению, уже не применяется. Но код открытый, кто знает?..
В данном случае речь идёт о том, что итератор определяет обход последовательности и выдачу элементов.
При этом итератор не знает, что будут делать с выданными им элементами: умножать, складывать, что-то ещё.
Из проблем, навскидку:
filter
послеtransform
, который читает из файла или делает что-то долгое). При этом код корректен, компилируется и работает.shared_ptr
, а это уже лишний уровень косвенности.Смотря как сделать :).
Можно сделать сбивающим, но многопозиционным: