2015-05-14 3 views
5

Я переусердствовал (некоторые могут сказать, что понимают, давайте посмотрим, что произойдет), константа контейнеров STL и их элементов.Контейнеры STL и их элементы - когда использовать const?

Я искал обсуждение этого вопроса, но результаты были на удивление скудными. Поэтому я не обязательно ищу здесь определенный ответ, я был бы так же доволен обсуждением, которое снова заставляет меня двигаться в моей голове.

Предположим, у меня есть класс, который хранит std :: strings в std :: vector. Мой класс - это словарь, который читает слова из словаря. Они никогда не будут изменены. Таким образом, представляется целесообразным объявить его как

std::vector<const std::string> m_myStrings; 

Однако я прочитал рассеянные комментарии, которые вы не должны использовать константные элементы в станд :: вектор, так как элементы должны быть предоставлены.

Вопрос:

  • Существуют случаи, когда сопзЬ элементы используются в станд :: вектор (за исключением хаки и т.д.)?

  • Элементы const используются в других контейнерах? Если да, то какие и когда?

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

ответ

2

No, по этой причине вы заявляете.

+0

Хорошо, достаточно простого нет - по крайней мере, это означает, что я правильно понял. EDIT: Я очень хочу, чтобы компилятор мог поймать это использование. Я понимаю, что есть причины для этого не делать этого. – Leander

+0

@ Leander: Хорошо, достаточно простого «Ok». –

-1

рассмотреть возможность использования

std::vector<std::shared_ptr<const std::string>> 

вместо этого?

+0

Спасибо за предложение, но я стараюсь избегать указателей здесь, даже умных. :) – Leander

+0

_ «В первую очередь я говорю о типах значений как о элементах, а не о указателях». _ –

+0

В любом случае это не отвечает на вопрос. – juanchopanza

2

В контексте std::vector, я не думаю, что имеет смысл использовать const классификатор с параметром шаблона, так как std::vector динамична по своей природе и может потребоваться «переместить» в памяти для того, чтобы «изменить размер " сам.

В стандарте C++ 03 std::vector гарантированно хранится в непрерывной памяти. Это почти требует, чтобы std::vector был реализован с помощью какой-либо формы массива. Но как мы можем создать динамический массив, изменяющий размер? Мы не можем просто просто «добавить» память к ее концу - для этого потребуется либо дополнительный узел (и связанный список), либо физически помещать наши дополнительные записи в конец массива, который был бы либо из- или требуют от нас просто резервировать больше памяти в первую очередь.

Таким образом, я бы предположил, что std::vector нужно будет выделить дополнительный массив, скопировать или переместить его элементы в конец массива, а затем удалить старый.

не гарантируется, что перемещение или копирование задания для каждого шаблона-состоянии объекта для std::vector бы не изменить основной объект перемещается или копируется - это считается хорошим тоном делать добавить const спецификатор, но это не требуется. Поэтому мы не можем разрешить std::vector<const T>.

Похожие: How is C++ std::vector implemented?

4

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

Инкапсуляция может помочь здесь.

У вас есть класс vector<string>, но сделайте его закрытым. Затем добавьте аксессуар в свой класс, который возвращает const vector<string> &, и заставьте его пройти через это.

Звонки не могут изменить вектор, и operator [] на этот вектор передаст их const string &, что именно то, что вы хотите.

+0

Это хорошее предложение, и это в значительной степени то, что я решил сделать. Поскольку ваше решение требует создания копии всего вектора, я, вероятно, предоставил бы интерфейс, подобный этому: 'void iterateWords (std :: function func);': then callers может снабжать лямбда-функцию, чтобы делать все, что захочет, со строками. – Leander

Смежные вопросы