Предоставляет ли C ++ 11 вектор ?

Требования к контейнерам изменились с C ++ 03 на C ++ 11. Хотя C ++ 03 имеет общие требования (например, конструктивность копирования и назначение для вектора), C ​​++ 11 определяет мелкозернистые требования к каждой операции с контейнером (раздел 23.2).

В результате вы можете, например, хранить тип, который можно скопировать, но не назначать – например, структуру с константным элементом – в векторе, если вы выполняете только определенные операции, которые не требуют назначения (конструкция и push_back являются такими операции, insert отсутствует).

Мне интересно: означает ли это, что стандарт теперь позволяет использовать vector ? Я не вижу причин, по которым это не должно быть – const T , как структура с членом-константой, является типом, который является конструктивным, но не назначаемым, но я, возможно, что-то пропустил.

(Часть того, что заставляет меня думать, что я, возможно, что-то пропустил, состоит в том, что магистраль gcc сбой и ожоги, если вы пытаетесь создать vector , но это нормально с vector где T имеет член const).

Нет, я считаю, что требования распределителя говорят, что T может быть «неконстантным, не ссылочным типом объекта».

Вы не сможете многое сделать с вектором постоянных объектов. И const vector будет почти таким же.


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

Поэтому, чтобы добавить некоторые правильные ссылки:

Для стандарта C ++ 03, который у меня есть на бумаге, в таблице 31 в разделе [lib.allocator.requirements] говорится:

T, U any type

Не то, чтобы какой-либо тип действительно работал.

Итак, следующий стандарт, C ++ 11, говорит в близком проекте в [allocator.requirements] и теперь в таблице 27:

T, U, C any non-const, non-reference object type

который чрезвычайно близок к тому, что я изначально написал из памяти. Это и вопрос.

Однако в C ++ 14 ( черновик N4296 ) Таблица 27 теперь говорит:

T, U, C any non-const object type

Возможно, потому что ссылка, возможно, не является типом объекта в конце концов?

И теперь в C ++ 17 ( черновик N4659 ) приведена таблица 30:

T, U, C any cv-unqualified object type (6.9)

Таким образом, не только исключается const , но и volatile . Наверное, старые новости все равно, и просто разъяснение.


Пожалуйста, также ознакомьтесь с информацией из первых рук Говарда Хиннанта , прямо сейчас.

Обновить

В соответствии с принятым (и правильным) ответом я прокомментировал в 2011 году:

Итог: мы не проектировали контейнеры для хранения const T Хотя я и подумал. И мы пришли очень близко к тому, чтобы сделать это случайно. Насколько я знаю, текущая точка прилипания – это пара перегруженных функций-членов address в распределителе по умолчанию: Когда T const , эти две перегрузки имеют одну и ту же подпись. Простым способом исправить это будет специализировать std::allocator и удалить одну из перегрузок.

С наступающим проектом C ++ 17 мне кажется, что мы теперь легализовали vector , и я также считаю, что мы сделали это случайно . 🙂

P0174R0 удаляет перегрузки address из std::allocator . P0174R0 не упоминает о поддержке std::allocator как части своего обоснования.

коррекция

В комментариях ниже TC правильно отмечает, что перегрузки address устарели , а не удалены. Виноват. Устаревшие члены не отображаются в 20.10.9, где определяется std::allocator , но вместо этого отнесены к разделу D.9. Я забыл просканировать главу D для этой возможности, когда я разместил это.

Спасибо TC за исправление. Я предполагал удалить этот вводящий в заблуждение ответ, но, возможно, лучше оставить его с этой коррекцией, чтобы, возможно, это оставило бы кого-то другого неверным для понимания спецификации так же, как и я.

Несмотря на то, что у нас уже есть очень хорошие ответы на это, я решил внести более практичный ответ, чтобы показать, что может и что нельзя сделать.

Так что это не работает:

 vector vec; 

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

 vector> vec; 

T уже не const , но vector держит shared_ptr s, а не T s.

С другой стороны, это работает:

 vector vec; vector vec; // the same as above 

Но в этом случае const указывает объект, на который указывает, а не сам указатель (что и хранит вектор). Это будет эквивалентно:

 vector> vec; 

Это нормально.

Но если мы поместим const в конец выражения, теперь он превратит указатель в const , поэтому следующее не будет компилироваться:

 vector vec; 

Я сбиваю с толку, соглашусь, но вы привыкли к этому.

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

 vector> vec; 

Если это так, когда вы хотите обеспечить, чтобы только vec владел своими товарами. Или, если вам нужна динамика перемещения элементов в vec и в какой-то момент их вытащите.

Как указывалось, семантика указателя const может вводить в заблуждение, но shared_ptr и unique_ptr не являются. const unique_ptr является указателем константы, а unique_ptr unique_ptr является константой, как и следовало ожидать.

  • R управления памятью / не может выделить вектор размера n Mb
  • Как использовать векторные чертежи в Android API ниже 21?
  • Поиск всех позиций для нескольких элементов в векторе
  • Самый быстрый способ найти второе (третье ...) наивысшее / наименьшее значение в векторе или столбце
  • Почему я не могу создать вектор lambdas (одного типа) в C ++ 11?
  • Ошибка производительности для vector :: size () в цикле
  • Как вычислить нормальный вектор сегмента линии?
  • Каковы различия между векторными и списковыми типами данных в R?
  • Вычисление двумерного векторного изображения
  • Векторы, структуры и std :: find
  • Ошибка времени компиляции C ++: ожидаемый идентификатор до числовой константы
  • Давайте будем гением компьютера.