Доступ к элементам вектора в С++?
Я часто обнаружил, что люди используют скобки массива [] и нормальную векторную функцию .at(). Почему существуют два отдельных метода? Каковы преимущества и недостатки обоих? Я знаю, что .at() безопаснее, но есть ли ситуации, когда .at() нельзя использовать? И если .at() всегда безопаснее, зачем использовать скобки массива [].
Я искал, но не мог найти аналогичный вопрос. Если такие вопросы уже существуют, отправьте мне его, и я удалю этот вопрос.
Ответы
Ответ 1
std::vector::at()
защищает вас от доступа к элементам массива вне пределов, бросая исключение out_of_bounds
в отличие от оператора []
, который не предупреждает или не бросает исключения при доступе за пределы векторных границ.
std::vector
является/рассматривался как c++ замена/конструкция для массивов переменной длины (VLA) в c99. Для того, чтобы массивы c-style были легко заменяемы на std::vector
, необходимо, чтобы векторы обеспечивали аналогичный интерфейс, аналогичный интерфейсу массива, поэтому вектор предоставляет оператор []
для доступа к его элементам. В то же время комитет по стандартам C++, возможно, также ощущал необходимость обеспечения дополнительной безопасности для std::vector
по массивам c-style и, следовательно, они также предоставляли метод std::vector::at()
, который его предоставляет.
Естественно, что метод at()
проверяет размер вектора перед его разыменованием, и это будет небольшим накладным (возможно, незначительным в большинстве случаев использования) по доступу к элементам с помощью []
, So std::vector
предоставляет вам как варианты должны быть безопасными или быть быстрее за счет управления безопасностью самостоятельно.
Ответ 2
Как отмечали другие, at()
выполняет проверку границ, а []
- нет. Две причины, о которых я могу думать, предпочитают []
:
- Чистый синтаксис
- Производительность. При переходе через элементы вектора часто бывает слишком сложно и очень дорого выполнять проверку границ на каждой итерации.
Ответ 3
at()
Плюсы:
- безопасно, поскольку исключение генерируется, если массив выходит за пределы
Минусы:
- медленный доступ
- больше символов для ввода
operator[]
Плюсы:
- быстрый доступ из-за отсутствия ограничений.
- меньше символов для ввода
- "интуитивный" доступ к элементу массива
Минусы:
- небезопасно из-за отсутствия ограничений.
Ответ 4
Персональный выбор
Причина, по которой некоторые люди используют Оператор подстроки, заключается в том, что они интуитивно понятны, поскольку вектор похож на массив, обращающийся к элементам таким образом, просто ставится как "синтаксический сахар", что означает, что он выглядит лучше.
Некоторые люди предпочитают []
, а другие предпочитают .at()
, это личный выбор.
Технический выбор
Предполагая, что вы говорите только о доступе, функция .at()
проверяет границы и выдает исключение, когда вы пытаетесь получить доступ к элементу за пределами. Функция "безопаснее", но если вы проверяете себя самостоятельно, не стесняйтесь использовать оператора индексирования!
Так что действительно вам решать, какой стиль доступа вы используете!
Ответ 5
Вы правы .at() безопаснее, потому что он проверит границы массива. оператор [] пропускает проверку и undefined, если вы делаете незаконный доступ.
Традиционный доступ к массиву в C/С++ никогда не проверялся рамками массива, и еще в 90-х годах до внедрения Java многие считали, что это добавит недопустимые накладные расходы. Я считаю, что в целом это не так сегодня, и это было не так верно, как многие считали в то время. Я уверен, что есть случаи, когда это имеет значение, но в целом вам лучше начать безопасно и переключиться, если вы найдете настоятельную необходимость сделать это.
Ответ 6
Оператор нижнего индекса имеет меньшую типизацию, что делает код более понятным. Кроме того, рефакторинг в/из массива C приходит естественным образом.
Ответ 7
Я использую STLPort 5.2.
Кажется, что at()
выполняет проверку диапазона.
ссылка at(size_type __n) { _M_range_check(__n); return (*this)[__n]; }