Должен ли я использовать std :: vector :: at () в моем коде - PullRequest
16 голосов
/ 02 августа 2011

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

Так есть ли веская причина, почему кто-тоиспользуйте at() вместо []?

Ответы [ 6 ]

20 голосов
/ 02 августа 2011

Если у вас есть основания полагать, что индекс не находится под вашим контролем, или если поток управления особенно сложен и вы отслеживаете ошибки, то вы можете использовать at() на этапе отладки, но не внутри циклы или любая ситуация, когда вы знаете, что индекс безопасен.

Даже в других ситуациях вы должны либо предварительно проверить индекс (например, если он введен пользователем), либо, если вы просто получаете значение из сложного алгоритма, используйте assert и исправьте ошибку, если она есть. [Править.] Или, возможно, если вы пишете очень сложный алгоритм и вы не уверены, что все ваши индексы всегда действительны, вы можете использовать at() внутри этого алгоритма и попробовать выполнить попытку блок - но даже здесь предпочтительнее быть оскорбительным и использовать с утверждениями. [/]

Лично я не вижу веских причин для at() выживания в коде релиза. Возможно, вы могли бы придумать несколько примеров, в которых вы хотите использовать обработку исключений в качестве удобного способа управления потоком управления, но любой такой вариант использования будет очень ситуативным.

9 голосов
/ 02 августа 2011

Разница между at() и operator[] заключается в том, что at() сигнализирует, если запрошенная позиция выходит за пределы диапазона, генерируя исключение out_of_range.
Таким образом, с помощью at() вы можете реагировать на состояние ошибки,Использование оператора [] для доступа к вектору вне индекса приведет к неопределенному поведению.

3 голосов
/ 02 августа 2011

at делает проверку диапазона, а operator[] - нет. Например, если вы передадите -1 в at(), будет выброшено std::out_of_range. Но если вы проделаете то же самое с operator[], он рухнет или произойдет странное.

Если вы абсолютно уверены, что с индексом все в порядке или вы хотите выполнить проверку самостоятельно, используйте operator[].

1 голос
/ 02 августа 2011

at () генерирует исключение out_of_range, которое [] не делает.

Таким образом, хотя [] может привести к аварийному завершению работы вашего приложения, если вы попытаетесь получить доступ к чему-либо вне диапазона, at () позволит вам обработать ошибку во время выполнения.

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

1 голос
/ 02 августа 2011

Если вы не используете исключения в качестве сигнальной системы, разница в том, что vector::at() ВСЕГДА будет генерировать исключение при попытке доступа к индексу за пределами границ. vector::operator[] может либо вернуть неопределенное значение, либо выдать исключение нарушения прав доступа (или аварийное завершение работы).

1 голос
/ 02 августа 2011

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

...