Классы более приятные, но если прецедент ограничен, например. один метод тела, расточительно его создавать. Если у вас есть класс Pair , вы можете специализироваться на этом, не создавая новый класс.
Нет, я считаю, что требования распределителя говорят, что T может быть «неконстантным, не ссылочным типом объекта».
Вы не смогли бы многое сделать с вектором постоянных объектов , И const vector<T>
в любом случае будет практически одинаковым.
Много лет спустя этот быстрый и грязный ответ все еще, кажется, привлекает комментарии и голоса. Не всегда. : -)
Итак, чтобы добавить некоторые правильные ссылки:
Для стандарта C ++ 03, который у меня есть на бумаге, Table 31 в разделе [lib.allocator.requirements] говорит:
blockquote>
T, U any type
Не работает любой тип .
Итак, следующий стандарт, C ++ 11, говорит в закрытом проекте в [allocator.requirements] и теперь в таблице 27:
blockquote>
T, U, C any non-const, non-reference object type
, который очень близок к тому, что я изначально написал из памяти. Это также вопрос, о котором идет речь.
Однако в C ++ 14 ( черновик N4296 ). В таблице 27 теперь говорится:
blockquote>
T, U, C any non-const object type
Возможно, потому что ссылка, возможно, не является типом объекта?
И теперь в C ++ 17 ( черновик N4659 ]), это таблица 30, в которой говорится:
blockquote>
T, U, C any cv-unqualified object type (6.9)
Таким образом, не только
const
исключено, но иvolatile
. В любом случае, старые новости и просто разъяснение.
Также см. информацию из первых рук Говарда Хиннанта , которая находится прямо внизу.
В дополнение к другим ответам, другой подход заключается в том, чтобы использовать:
vector<unique_ptr<const T>> vec;
Если это так, когда вы хотите обеспечить, чтобы только vec
владел своими элементами. Или, если вы хотите, чтобы динамические перемещения элементов в vec
и в какой-то момент их вытеснили.
Как указывалось, семантика указателя const
может быть запутанной, но shared_ptr
и unique_ptr
aren «т. const unique_ptr<T>
является указателем const, а unique_ptr<const T>
является константой, как и следовало ожидать.
Обновить
В соответствии с принятым (и правильным) ответом я прокомментировал в 2011 году:
Нижняя строка: мы не создавали контейнеры для хранения
blockquote>const T
. Хотя я и подумал. И мы пришли очень близко к тому, чтобы сделать это случайно. Насколько мне известно, текущая точка привязки - это пара перегруженных функцийaddress
-члена в распределителе по умолчанию: КогдаT
-const
, эти две перегрузки имеют одну и ту же подпись. Легкий способ исправить это было бы специализациейstd::allocator<const T>
и удалением одной из перегрузок.С предстоящим проектом C ++ 17 мне кажется, что мы теперь легализованы
vector<const T>
, и я также считаю, что мы это сделали случайно . : -)P0174R0 удаляет
address
перегрузки сstd::allocator<T>
. P0174R0 не упоминает о поддержкеstd::allocator<const T>
как части его обоснования.Коррекция
В комментариях ниже T.C. правильно отмечает, что перегрузки
address
являются устаревшими , а не удалены. Виноват. Устаревшие члены не отображаются в 20.10.9, гдеstd::allocator
определен, но вместо этого отнесены к разделу D.9. Я забыл просканировать главу D для этой возможности, когда я разместил это.Спасибо T.C. для исправления. Я предполагал удалить этот вводящий в заблуждение ответ, но, возможно, лучше оставить его с этой коррекцией, чтобы, возможно, это оставило бы кого-то еще от неправильного считывания спецификации так же, как и я.
address
.
– T.C.
27 September 2016 в 21:01
Несмотря на то, что у нас уже есть очень хорошие ответы на это, я решил внести более практичный ответ, чтобы показать, что может и что не может быть сделано.
Так что это не работает:
vector<const T> vec;
Просто прочитайте другие ответы, чтобы понять, почему. И, как вы, возможно, догадались, это тоже не сработает:
vector<const shared_ptr<T>> vec;
T
больше не const
, но vector
удерживает shared_ptr
s, а не T
s.
С другой стороны, это работает :
vector<const T *> vec;
vector<T const *> vec; // the same as above
Но в этом случае const указывает объект, на который указывает, а не самого указателя (что и хранит вектор). Это было бы равнозначно:
vector<shared_ptr<const T>> vec;
Что хорошо.
Но если мы положим const
в конец выражения, теперь он превращает указатель в const
, поэтому следующее не будет компилироваться:
vector<T * const> vec;
Немного сбивает с толку, согласен, но вы привыкли к этому.
address
-члена в распределителе по умолчанию: Когда T const, эти две перегрузки имеют одну и ту же подпись. Простым способом исправить это было бы специализироватьstd::allocator<const T>
и удалить одну из перегрузок. – Howard Hinnant 5 August 2011 в 14:28push_back
. Но если это не разрешено дизайном, нам лучше не делать этого. Мне было просто любопытно. – HighCommander4 5 August 2011 в 21:19std::vector<const T>
именно потому, что он очень похож наconst std::vector<T>
, но без отрицательных последствий последнего для класса, который его удерживает. Фактически,std::vector<const T>
ТОЧНО, что мне нужно семантически в большинстве случаев, когда я используюvector
. Теперь я должен отказатьсяconst
- вместе с надежностью, которую он обеспечивает. – Violet Giraffe 24 June 2016 в 07:21