简体   繁体   中英

Accesing object stored in vector: use std::vector::at or std::vector::operator[]?

Is there really any difference between using at and brackets [] while accessing elements of vector?

I saw same people to prefer myvector.at() above myvector[] , is there something that makes it more preferable, like better performance in some situations, or being common with some other languages?

主要区别在于, operator[]是未选中的,如果您尝试在向量的边界之外访问内存,则会导致未定义行为,而.at会检查索引,并且如果您尝试访问内存,则会抛出std :: out_of_range异常越界

The difference between std::vector::at and std::vector::operator[] is that at will throw a std::out_of_range exception if the index is invalid, while operator[] will have undefined behaviour if the index is invalid.

The only reason that you would ever strongly prefer at is if your algorithm depends on an exception being thrown for out-of-bounds input. This seems like a very rare use-case, since it is straightforward to avoid out-of-bounds accesses through conscientious use of size() before any indexing operation, and so out-of-bounds accesses would usually simply be programming errors.

Assuming that an out-of-bound access is a bug rather than a valid execution path, the breakdown of at vs operator[] is as follows:


at :

advantages

  • Guaranteed behaviour on all platforms
  • Gives the ability (somewhat) to manage bugs at runtime

disadvantages

  • Unclear whether out-of-bounds is a runtime error or a programming bug
  • Unable to be optimised in release builds

operator[] :

advantages

  • Gives more scope for bug management (for example, an implementation can provide an assert that captures all of the relevant context and breaks into a debugger or prints a debug message)
  • Can be optimised in release builds
  • Makes reasoning about code easier, as it makes it clear that an out-of-bounds access is a programming bug

disadvantages

  • Behaviour not guaranteed on all platforms
  • Can lead to security issues or other very major and hard-to-debug bugs, if an optimised implementation is chosen.

Overall, I would tend to almost always use operator[] , and choose either an optimised version or a debug version depending on my need. Converting bugs into runtime errors is rarely useful.

v.at(i) checks if i is a valid index (ie, 0 <= i < v.size() ) and throws an exception if it is not. v[i] performs no such check and just tries to access the underlying buffer, and will (potentially) segfault* if i was not valid.

I would use [] if you know your index is valid.

* As Mankarse says accessing past the bounds of an array is undefined behavior. This specific instance of UB often results in segfaults, but could also just do other things you don't want/weren't expecting.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM