C++ <vector> at function
Among all the ways to access vector elements,atis the safest one because it providesBounds checking。
atis a member function of container classes, used toreturns the element at the specified position, while performing bounds checking. If the index is out of bounds, it throwsstd::out_of_rangean exception.
atimplements safe element access, allowing you to catch and handle out-of-bounds errors at runtime.
Word Definitions: atmeaning "at", i.e., gets the element at the specified position.
Basic syntax and parameters
atis a member function of the container class, so you need to have a container object first, and then use the dot operator.to call it.
Syntax format
reference at(size_type pos); const_reference at(size_type pos) const;
Parameter description
- Parameter:
pos- Type:
size_type(an unsigned integer type, usuallysize_t) - Description: The position (index) of the element to access. The index starts at 0, and the maximum valid index is
size() - 1。
- Type:
Function description
- Return Value: returns the element at the specified positionReference. If the container is a const container, it returns a const reference.
- Effect: Returns the element at the specified position. If the index is outside the valid range (
pos >= size()), it will throwstd::out_of_rangean exception. - difference from operator[]:
atperforms bounds checking,operator[]does not perform bounds checking (out-of-bounds behavior is undefined).
Example
Let's thoroughly master this through a series of examples, from simple to complexatUsage.
Example 1: Basic usage - accessing elements
Example
#include <vector>
#include <stdexcept> // Contains exception handling header file
int main() {
// 1. Create a vector and add some elements
std::vector<int> numbers = {10, 20, 30, 40, 50};
std::cout << "The size of the vector is: " << numbers.size() << std::endl;
// 2. Use at to access elements
std::cout << First element (at(0)): << numbers.at(0) << std::endl;
std::cout << Second element (at(1)): << numbers.at(1) << std::endl;
std::cout << Third element (at(2)): << numbers.at(2) << std::endl;
std::cout << Last element (at(4)): << numbers.at(4) << std::endl;
// 3. Use a loop to access all elements
std::cout << "All elements: ";
for(size_t i = 0; i < numbers.size(); ++i) {
std::cout << numbers.at(i) << " ";
}
std::cout << std::endl;
return 0;
}
Expected output:
vector的大小是: 5 第一个元素 (at(0)): 10 第二个元素 (at(1)): 20 第三个元素 (at(2)): 30 最后一个元素 (at(4)): 50 所有元素: 10 20 30 40 50
Code analysis:
numbers.at(0)Return the first element10(indices start from 0).numbers.at(4)returns the last element50(becausesize()is 5, valid indices are 0-4).- using loops and
atcan safely traverse all elements.
Example 2: catching an out-of-bounds exception
atThe main advantage is that it can throw exceptions, allowing us to handle out-of-bounds errors.
Example
#include <vector>
#include <stdexcept>
int main() {
std::vector<int> numbers = {10, 20, 30};
// Try to access an out-of-bounds position
try {
std::cout << Trying to access at(10)... << std::endl;
int value = numbers.at(10); // This will throw an exception
std::cout << Value: << value << std::endl;
}
catch(const std::out_of_range& e) {
std::cout << Caught exception: << e.what() << std::endl;
}
// Normal access
try {
std::cout << Access at(2): << numbers.at(2) << std::endl;
}
catch(const std::out_of_range& e) {
std::cout << Caught exception: << e.what() << std::endl;
}
return 0;
}
Expected output:
尝试访问 at(10)... 捕获到异常: vector::_M_range_check: __pos (which is 10) >= this->size() (which is 3) 访问 at(2): 30
Code analysis:
- When accessing
at(10)when the index is out of range, it throwsstd::out_of_rangean exception. catch(const std::out_of_range& e)Catch exception,e.what()returns the description of the exception.- normal index access does not throw exceptions.
Example 3: Comparison of at and operator[]
Comparisonatandoperator[]Differences in behavior.
Example
#include <vector>
#include <stdexcept>
int main() {
std::vector<int> numbers = {10, 20, 30};
std::cout << Use at() to access elements: << std::endl;
// at() performs bounds checking
for(size_t i = 0; i <= numbers.size(); ++i) {
try {
std::cout << "at(" << i << ") = " << numbers.at(i) << std::endl;
}
catch(const std::out_of_range& e) {
std::cout << "at(" << i << ) Out of range! << std::endl;
}
}
std::cout << "\nUse operator[] to access elements: << std::endl;
// operator[] does not perform bounds checking, out-of-bounds behavior is undefined
for(size_t i = 0; i <= numbers.size(); ++i) {
std::cout << "numbers[" << i << "] = " << numbers[i] << std::endl;
}
return 0;
}
Code analysis:
at()It throws an exception when out of bounds, and you can choose to catch and handle it.operator[]the behavior when out of bounds is undefined, and may return garbage values, crash, or produce other unpredictable results.- in production code, for safety, it is recommended to use
at()insteadoperator[], especially when the index comes from user input or external data.
Example 4: modifying element values
atIt returns a reference, so it can be used to modify the value of the element.
Example
#include <vector>
int main() {
std::vector<int> numbers = {10, 20, 30};
std::cout << "Before modification: ";
for(size_t i = 0; i < numbers.size(); ++i) {
std::cout << numbers.at(i) << " ";
}
std::cout << std::endl;
// Use at() to get a reference and modify the element
numbers.at(0) = 100;
numbers.at(1) = 200;
numbers.at(2) = 300;
std::cout << "After modification: ";
for(size_t i = 0; i < numbers.size(); ++i) {
std::cout << numbers.at(i) << " ";
}
std::cout << std::endl;
return 0;
}
Expected output:
修改前: 10 20 30 修改后: 100 200 300
Code analysis:
numbers.at(0) = 100;The value of the first element was modified through the reference.- This demonstrates
at()returns a modifiable lvalue reference.
other extensions