Как стать автором
Обновить

Комментарии 8

Хранить в одном контейнере разнотипные объекты можно (например, использовать std::variant или динамический кортеж), но в нашем случае довольно накладно. 

На всякий случай добавлю, что boost::any_range не бесплатен, он выделяет динамическую память и использует виртальные функции, вряд ли дешевле variant'а.

Справедливо. Надо бы замерить.

Предварительные результаты замеров в попугаях:
Обычные итераторы: 26
boost::any_iterator: 215
variant_iterator (самописный): 32


Также эксперементирую самописным any_iterator без виртуальных фунций, но быстрее пока не выходит.

А как может быть any_iterator без виртуальных функций? Тогда он должен знать все типы, которые он должен затайперэйзить, а это уже не будет any_iterator. Концептуально, по моему, быстрее варианта ничего не получится. Из-за знания типов итераторов исходных рэнжей на этапе компиляции можно избавиться от динамической аллокации, а вместо виртуальных функций - switch по типу, который стоит примерно как виртуальный вызов.

Без виртуальных функций можно делать через механизм обобщённых обработчиков. Писал об этом тут: https://habr.com/ru/post/302372/#manager


Или можно посмотреть реализацию std::function в любой современной стандартной библиотеке.

Но это ничем не отличается от std::vaiant по производительности, но нужо знать конкретные классы, то есть ваш any_iterator Будет шаблоном, а весь сок в том, что это не шаблон.

Нет, типы знать не нужно. Шаблоном не будет :). Ну то есть будет, но параметры — не итераторы, а тип значения и категория.
Как-то так это можно сделать: https://pastebin.com/Z6wemSjB

А, ну здесь аллокация на куче в boost::any и самодельные виртуальные методы. От судьбы не уйдёшь.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории