Const-Correctness для элементов стандартных контейнеров

Следующее плохо:

vector<const int> vec;

Проблема в том, что тип шаблона должен быть назначаемым. Следующий код компилирует [EDIT: в Visual Studio 2010], демонстрируя проблему с вышеуказанным:

vector<const int> vec;
vec.push_back(6);
vec[0] += 4;

С более сложными типами это может быть серьезной проблемой.

Мой первый вопрос: есть ли причина для такого поведения? Мне кажется, что возможно создать const-контейнеры, которые запрещают вышеупомянутые, и неконстантные контейнеры, которые позволяют это.

Во-вторых, есть ли способ сделать контейнеры, которые работают таким образом?

В-третьих, что на самом деле происходит здесь (с типом пользователя)? Я понимаю, что это неопределенное поведение, но как STL вообще компилирует это?

5

Решение

Причина std::vector<T const> не допускается, что объект в векторе может потребоваться перестановка при вставке в другое место, чем в начале. Теперь член std::vector<T>::push_back(T const& v) концептуально эквивалентно (опуская параметр шаблона распределителя, так как он не имеет значения для этого обсуждения)

template <typename T>
void std::vector<T>::push_back(T const& v) {
this->insert(this->end(), v);
}

кажется, как это реализовано в некоторых реализациях. Теперь эта операция требует, в общем, чтобы некоторые объекты могли перемещаться и, таким образом, T Аргумент должен быть назначаемым. Кажется, что стандартная библиотека, поставляемая с MSVC ++, не делегирует операцию, а выполняет всю необходимую обработку, то есть изменяет размер массива и перемещает объекты соответствующим образом, когда заканчивается пространство, в push_back(), Не совсем понятно, какие требования предъявляются к типу T быть в состоянии использовать push_back(),

В принципе, контейнер, поддерживающий оба T const и insert() Операция в середине была бы возможна, однако: ничто не требует, чтобы внутреннее хранилище было T скорее, чем typename std::remove_const<T>::type выставляя T& в интерфейсе. Надо быть немного осторожнее с const-версия операций типа operator[]() потому что просто используя T const& в качестве типа возврата при T это какой-то тип S const приведет к типу S const const, В C ++ 2003 это было бы ошибкой, в C ++ 2011 я думаю, что const просто рухнули. Чтобы быть в безопасности, вы можете использовать typename std::add_const<T>::type&,

3

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector