Boost any_range против «канонической формы» - что является последним? - PullRequest
5 голосов
/ 09 апреля 2011

Boost's any_range документация гласит следующее:

Несмотря на то, что базовая any_iterator является самой быстрой из доступных реализаций, служебная нагрузка any_range все еще ощутима из-за стоимости вызовов виртуальных функций, необходимых для реализации приращения, уменьшения, продвижения, равенства и т. Д. Часто лучший выбор дизайна это преобразовать в каноническую форму .

Что автор подразумевает под «канонической формой»? Может кто-нибудь привести пример?

РЕДАКТИРОВАТЬ: Как предложено здесь, я задал тот же вопрос в списке рассылки продвинутых пользователей. Вот что сказал Нейл Гроувс, автор этого текста:

Например, копирование диапазона в вектор.

Да, это именно тот альтернативный дизайн, который я имел в виду при написании документации. Затраты на итерацию по any_range довольно значительны и часто плохо сравниваются с копированием конкретного типа результата в контейнер, такой как вектор. Однако это не всегда так, и некоторые пользователи Boost.Range хотели бы иметь возможность реализовывать алгоритмы, которые работают с экземплярами any_range. Иногда желательно разрешить, например, использование алгоритмов из разделяемой библиотеки, которая поддерживает различные контейнеры. Использование any_range также может иметь смысл, когда число проходов по диапазону мало, но объем памяти нижележащего контейнера очень велик.

Во многих случаях снижение производительности не имеет значения. Я хотел убедиться, что я никого не вводил в заблуждение в широком распространении использования any_range. Я считаю, что допустимые значения для этого класса немногочисленны, но иногда это точно правильный выбор дизайна. Я буду улучшать документацию с некоторыми дополнительными разъяснениями и примерами в должное время.

Ответы [ 2 ]

3 голосов
/ 09 апреля 2011

Я думаю, что они означают преобразование вашего диапазона в std::vector или любой другой стандартный контейнер в вашем проекте и возвращение итератора в него.

Компромисс между стоимостью создания копии вашего диапазона от исходного типа диапазона до канонического типа контейнера и стоимостью выделения кучи и вызовов виртуальных функций, связанных с стиранием типа, используемым для реализации any_range. В зависимости от количества элементов в диапазоне, размера каждого элемента и количества проходов в этом диапазоне один вариант может быть лучше другого.

3 голосов
/ 09 апреля 2011

Цель any_range состоит в том, чтобы обернуть некоторый конкретный тип итератора так, чтобы пользователям вашего кода не нужно было перекомпилировать, если вы измените детали этого базового итератора. Думайте об этом как Pimpl для итераторов.

В документации просто указывается, что всегда эффективнее (при времени выполнения ) непосредственно представлять базовый конкретный тип итератора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...