Обработка индексов вне диапазона - PullRequest
2 голосов
/ 17 марта 2011

Для класса контейнера, каким должно быть ожидаемое поведение, когда пользователь класса пытается установить значение, которое находится за пределами размера класса?

Рассматриваемый метод является методом «замены» (например, operator[]), а не методом «добавления» (например, operator+=).

Я могу сгенерировать исключение out_of_range или просто изменить размер контейнера, чтобы вместить дополнение.

Ответы [ 4 ]

4 голосов
/ 17 марта 2011

Исключение вне диапазона здесь более уместно, потому что семантика «замена» обычно означает, что вызывающая сторона предполагает / утверждает, что в указанном индексе есть данные, которых нет.

3 голосов
/ 17 марта 2011

Для std::vector::operator[] ошибка домена вызывает неопределенное поведение. Для std::map::operator[] ошибка домена создает новую запись. Я думаю, вопросы дизайна:

  • Сколько стоит удлинить контейнер? То есть, вы можете создать только один элемент (например, map::operator[]), или вам нужно создать все промежуточные элементы (например, vector::operator[])

  • Насколько дорогая проверка диапазона по сравнению с функцией доступа? В map проверка диапазона становится бесплатной после запуска функции доступа. В vector проверка диапазона приблизительно удваивает стоимость доступа.

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

1 голос
/ 18 марта 2011

Еще один момент, о котором еще не говорилось, заключается в том, что иногда может быть полезно предусмотреть особый случай с одним случаем для увеличения размера класса.Идея состоит в том, что у класса может быть инвариант, что элементы [0] к элементу [длина-1] были правильно назначены.Если кто-то пытается записать в item [K] с K> = length + 1, может возникнуть необходимость создать новые элементы [length..K-1] с неизвестными значениями, нарушая инвариант класса.С другой стороны, если кто-то пишет в item [length], он может увеличивать длину на единицу и поддерживать инвариант класса.

1 голос
/ 17 марта 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...