Доступ к элементам вектора в C ++? - PullRequest
34 голосов
/ 22 ноября 2011

Я часто замечал, что люди используют скобки [] и обычную векторную функцию .at ().Почему есть два отдельных метода?Каковы преимущества и недостатки обоих?Я знаю, что .at () безопаснее, но есть ли ситуации, когда .at () нельзя использовать?И если .at () всегда безопаснее, зачем использовать скобки для массива [].

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

Ответы [ 7 ]

51 голосов
/ 22 ноября 2011

std::vector::at() защищает вас от доступа к элементам массива вне границ, вызывая исключение out_of_bounds в отличие от оператора [], который не предупреждает и не выдает исключения при доступе за пределами векторных границ.

std::vector считается / считался заменой / конструкцией c ++ для массивов переменной длины (VLA) в c99.Для того чтобы массивы в стиле c легко заменялись на std::vector, было необходимо, чтобы векторы обеспечивали интерфейс, аналогичный интерфейсу массива, поэтому вектор предоставляет оператор [] для доступа к его элементам.В то же время, комитет по стандартам C ++, возможно, также почувствовал необходимость в обеспечении дополнительной безопасности для std::vector над массивами в стиле c, и, следовательно, он также предоставил метод std::Vector::at(), который его предоставляет.Метод проверяет размер вектора перед разыменованием, и это приведет к небольшим издержкам (возможно, незначительным в большинстве случаев использования) при доступе к элементам с помощью [], поэтому std::vector предоставляет вам оба варианта, чтобы быть безопасными или быстрееза счет управления безопасностью самостоятельно.

12 голосов
/ 22 ноября 2011

Как уже упоминалось, at() выполняет проверку границ, а [] - нет. Две причины, по которым я могу предпочесть []:

  1. Чистый синтаксис
  2. Производительность. При циклическом просмотре элементов вектора часто бывает неудобно выполнять проверку границ на каждой итерации.
10 голосов
/ 22 ноября 2011

at()

Плюсы:

  • безопасно, потому что исключение выдается, если массив выходит за пределы

Минусы:

  • медленный доступ
  • больше символов для ввода

operator[]

Плюсы:

  • быстрый доступ из-за отсутствия проверки границ
  • меньше символов для ввода
  • «Интуитивно понятный» доступ к элементу массива

Минусы:

  • небезопасно из-за отсутствия проверки границ
2 голосов
/ 22 ноября 2011

Вы правы .at () безопаснее, потому что он будет проверять границы массива.operator [] пропускает проверку и не определен, если вы делаете недопустимый доступ.

Традиционный доступ к массивам в C / C ++ никогда не проверял границы массивов, и еще в 90-х годах до появления Java многие считали, чтодобавил бы неприемлемые накладные расходы.Я считаю, что в целом это не так сегодня, и это было не так, как многие полагали в то время.Я уверен, что есть случаи, когда это имеет значение, но в целом вам лучше начать с безопасного и переходного периода, если вы обнаружите в этом настоятельную необходимость.

2 голосов
/ 22 ноября 2011

Персональный выбор

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

Некоторые люди предпочитают [], а другие предпочитают .at(), это личный выбор.

Технический выбор

Предполагая, что вы говорите только о доступе, функция .at() выполняет проверку границ и выдает исключение при попытке получить доступ к элементу за пределами. Функция «безопаснее», но если вы сами проверяете границы, не стесняйтесь использовать оператор индекса!

Так что на самом деле вам решать, какой стиль аксессуара вы используете!

1 голос
/ 22 ноября 2011

Я использую STLPort 5.2. Кажется at() делает проверку диапазона.

ссылка at(size_type __n) { _M_range_check(__n); return (*this)[__n]; }

1 голос
/ 22 ноября 2011

Оператор подписки требует меньше ввода, что делает код более понятным.Кроме того, рефакторинг в / из массива C происходит естественным образом.

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