Скажите, что у меня есть класс C ++ Container
, который содержит некоторые элементы типа Element
. По разным причинам неэффективно, нежелательно, не нужно, нецелесообразно и / или невозможно (1) модифицировать или заменить содержимое после создания. Что-то вроде const std::list<const Element>
(2).
Container
может отвечать многим требованиям концепций STL «контейнер» и «последовательность». Он может предоставлять различные типы, такие как value_type
, reference
и т. Д. Он может предоставлять конструктор по умолчанию, конструктор копирования, тип const_iterator
, begin() const
, end() const
, size
, empty
, все операторы сравнения, и, возможно, некоторые из rbegin() const
, rend() const
, front()
, back()
, operator[]()
и at()
.
Однако Container
не может предоставить insert
, erase
, clear
, push_front
, push_back
, неконстантный front
, неконстантный back
, неконстантный operator[]
или неконстантный at
с ожидаемой семантикой. Таким образом, кажется, что Container
не может квалифицироваться как «последовательность». Кроме того, Container
не может предоставить operator=
и swap
, и он не может предоставить тип iterator
, который указывает на неконстантный элемент. Таким образом, он даже не может считаться «контейнером».
Есть ли какая-нибудь менее способная концепция STL, с которой встречается Container
? Есть ли «контейнер только для чтения» или «неизменный контейнер»?
Если Container
не соответствует определенному уровню соответствия, есть ли значение в частичном соответствии? Это вводит в заблуждение, чтобы сделать его похожим на «контейнер», когда он не подходит? Есть ли краткий, однозначный способ документировать соответствие, чтобы мне не приходилось явно документировать соответствующую семантику? И точно так же, способ документировать это так, чтобы будущие пользователи знали, что они могут использовать общий код только для чтения, но не ожидают, что мутирующие алгоритмы будут работать?
Что я получу, если я ослаблю проблему, чтобы Container
был Назначаемым (но его элементы - нет)? В этот момент возможны operator=
и swap
, но разыменование iterator
все еще возвращает const Element
. Container
теперь квалифицируется как "контейнер"?
const std::list<T>
имеет примерно тот же интерфейс, что и Container
. Означает ли это, что это не «контейнер» и не «последовательность»?
Сноска (1) У меня есть варианты использования, которые охватывают весь этот спектр. У меня есть класс "потенциальный контейнер", который адаптирует некоторые данные только для чтения, поэтому он должен быть неизменным. У меня есть потенциальный контейнер, который генерирует собственное содержимое по мере необходимости, поэтому он изменчив, но вы не можете заменить элементы так, как этого требует STL. У меня еще есть еще один потенциальный контейнер, который хранит свои элементы таким образом, что insert()
будет настолько медленным, что это никогда не будет полезным. И, наконец, у меня есть строка, которая хранит текст в UTF-8, предоставляя интерфейс, ориентированный на кодовую точку; изменчивая реализация возможна, но совершенно не нужна.
Сноска (2) Это только для иллюстрации. Я почти уверен, что std::list
требует присваиваемого типа элемента.