Правильный способ объявления `const`` boost :: range`s - PullRequest
1 голос
/ 22 марта 2019

При использовании boost::any_range, как правильно указать, что базовый контейнер (если есть) не должен быть изменен?

Например, с псевдонимом

template<typename T>
using Range = boost::any_range<T, boost::forward_traversal_tag>;

для объявления диапазона, который не способен изменять содержимое нижележащего контейнера или «источника данных», если он объявлен как

const Range<T> myRange;

или как

Range<const T> myRange;

Я подозреваю, что первая версия правильная. Но гарантированно ли будет сохранен контейнер const, если, например, я применю какой-либо из boost::adaptors?


Редактировать

Из документации , очевидно, метафункция range_iterator "выводит" const из нижележащего контейнера, объявляя диапазон с const T вместо T. То есть range_iterator::<const T>::type - это const_iterator (если базовый контейнер имеет такой тип элемента), а не iterator, поэтому контейнер нельзя изменить с помощью этого итератора.

Означает ли это, что Range<const T> также использует const_iterators для пересечения диапазона?

1 Ответ

0 голосов
/ 24 марта 2019

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

Из документации Boost.Range , мы можем видеть, что any_range принимаетследующие параметры шаблона:

template<
    class Value
  , class Traversal
  , class Reference
  , class Difference
  , class Buffer = any_iterator_default_buffer
>
class any_range;

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

Таким образом, диапазон const может быть объявлен как:

template<class C>
using ConstRange = boost::any_range<C, boost::forward_traversal_tag, const C, std::ptrdiff_t>
...