В чем разница между irange
а также counting_range
?
мне было нужно irange
быстро сгенерировать диапазон целых чисел, как это:
auto example = boost::irange(0, 5); /// result is {0, 1, 2, 3, 4}
Но заметил где-то пример (потерял ссылку), который говорит вместо counting_range
выполнить ту же задачу. Есть ли простое объяснение разницы между этими двумя?
Основное отличие состоит в том, что irange
это диапазон с произвольным доступом, в то время как counting_range
нет. counting_range
основан на Boost.Iterator’s counting_iterator
который использует все базовые целочисленные операции напрямую. Целые числа в C ++ почти соответствуют концепции итератора: единственное, чего не хватает, это operator*
, counting_iterator
обеспечивает operator*
как операция идентификации и передает все остальное в базовый тип.
Другое отличие состоит в том, что irange
также поддерживает приращения, отличные от 1.
Никто из них никогда не материализует весь диапазон целых чисел, по которым они перебираются, поэтому они оба используют O (1) памяти.
И то и другое irange
а также counting_range
моделировать диапазон произвольного доступа для целочисленных типов. Как counting_range
В документации указано, что ее категория итератора определяется по следующему алгоритму:
if (CategoryOrTraversal is not use_default)
return CategoryOrTraversal
else if (numeric_limits<Incrementable>::is_specialized)
return iterator-category(random_access_traversal_tag, Incrementable, const Incrementable&)
else
return iterator-category(iterator_traversal<Incrementable>::type, Incrementable, const Incrementable&)
Поэтому для простых диапазонов, таких как boost::irange(0, 10)
а также boost::counting_range(0, 10)
фактически нет никакой разницы (кроме типов каждого диапазона, конечно!).
Тем не мение, irange
также поддерживает итерацию с другим размером шага, например, boost::irange(0, 10, 2)
, а также counting_range
также поддерживает типы, которые являются только инкрементными и не полностью моделируют целое число.