C++ <vector> operator[] 运算符
在访问 vector 元素的所有方式中,operator[] 是最常用、最直接的一种,就像访问数组元素一样。
operator[] 是容器类的下标运算符,用于返回指定位置的元素,但不进行边界检查。它的用法与普通数组完全一致。
operator[] 提供了数组式的随机访问能力,让你能够快速访问任意位置的元素。
单词释义: operator[] 就是下标运算符,中括号就是数组访问的标志。
基本语法与参数
operator[] 是容器类的成员函数,像使用数组一样使用它即可。
语法格式
reference operator[](size_type pos); const_reference operator[](size_type pos) const;
参数说明
- 参数:
pos- 类型:
size_type(无符号整数类型,通常是size_t) - 描述: 要访问的元素的位置(索引)。索引从 0 开始,最大有效索引是
size() - 1。
- 类型:
函数说明
- 返回值: 返回指定位置元素的引用。如果容器是常量容器,则返回常量引用。
- 效果: 返回指定位置的元素。不会进行边界检查,越界访问的结果是未定义的。
- 与 at() 的区别:
operator[]不进行边界检查,速度稍快;at()会进行边界检查,越界时抛出异常。
实例
让我们通过一系列从简单到复杂的例子,彻底掌握 operator[] 的用法。
示例 1:基础用法 - 访问元素
实例
#include <iostream>
#include <vector>
int main() {
// 1. 创建一个 vector 并添加一些元素
std::vector<int> numbers = {10, 20, 30, 40, 50};
std::cout << "vector的大小是: " << numbers.size() << std::endl;
// 2. 使用 operator[] 访问元素
std::cout << "第一个元素 [0]: " << numbers[0] << std::endl;
std::cout << "第二个元素 [1]: " << numbers[1] << std::endl;
std::cout << "第三个元素 [2]: " << numbers[2] << std::endl;
std::cout << "最后一个元素 [4]: " << numbers[4] << std::endl;
// 3. 使用循环访问所有元素
std::cout << "所有元素: ";
for(size_t i = 0; i < numbers.size(); ++i) {
std::cout << numbers[i] << " ";
}
std::cout << std::endl;
return 0;
}
#include <vector>
int main() {
// 1. 创建一个 vector 并添加一些元素
std::vector<int> numbers = {10, 20, 30, 40, 50};
std::cout << "vector的大小是: " << numbers.size() << std::endl;
// 2. 使用 operator[] 访问元素
std::cout << "第一个元素 [0]: " << numbers[0] << std::endl;
std::cout << "第二个元素 [1]: " << numbers[1] << std::endl;
std::cout << "第三个元素 [2]: " << numbers[2] << std::endl;
std::cout << "最后一个元素 [4]: " << numbers[4] << std::endl;
// 3. 使用循环访问所有元素
std::cout << "所有元素: ";
for(size_t i = 0; i < numbers.size(); ++i) {
std::cout << numbers[i] << " ";
}
std::cout << std::endl;
return 0;
}
运行结果预期:
vector的大小是: 5 第一个元素 [0]: 10 第二个元素 [1]: 20 第三个元素 [2]: 30 最后一个元素 [4]: 50 所有元素: 10 20 30 40 50
代码解析:
numbers[0]返回第一个元素10(索引从 0 开始)。numbers[4]返回最后一个元素50(因为size()是 5,有效索引是 0-4)。- 使用循环和
operator[]可以遍历所有元素,用法与数组完全相同。
示例 2:修改元素的值
operator[] 返回的是引用,因此可以用来修改元素的值。
实例
#include <iostream>
#include <vector>
int main() {
std::vector<int> numbers = {10, 20, 30};
std::cout << "修改前: ";
for(size_t i = 0; i < numbers.size(); ++i) {
std::cout << numbers[i] << " ";
}
std::cout << std::endl;
// 使用 operator[] 获取引用并修改元素
numbers[0] = 100;
numbers[1] = 200;
numbers[2] = 300;
std::cout << "修改后: ";
for(size_t i = 0; i < numbers.size(); ++i) {
std::cout << numbers[i] << " ";
}
std::cout << std::endl;
return 0;
}
#include <vector>
int main() {
std::vector<int> numbers = {10, 20, 30};
std::cout << "修改前: ";
for(size_t i = 0; i < numbers.size(); ++i) {
std::cout << numbers[i] << " ";
}
std::cout << std::endl;
// 使用 operator[] 获取引用并修改元素
numbers[0] = 100;
numbers[1] = 200;
numbers[2] = 300;
std::cout << "修改后: ";
for(size_t i = 0; i < numbers.size(); ++i) {
std::cout << numbers[i] << " ";
}
std::cout << std::endl;
return 0;
}
运行结果预期:
修改前: 10 20 30 修改后: 100 200 300
代码解析:
numbers[0] = 100;通过引用修改了第一个元素的值。- 这展示了
operator[]返回的是可修改的左值引用。
示例 3:使用 auto 自动推导类型
结合 auto 关键字,可以更方便地使用 operator[]。
实例
#include <iostream>
#include <vector>
#include <string>
int main() {
std::vector<std::string> names = {"Alice", "Bob", "Charlie"};
// 使用 auto 自动推导类型
for(size_t i = 0; i < names.size(); ++i) {
auto& name = names[i]; // 推导为 std::string&
std::cout << "第 " << (i + 1) << " 个人: " << name << std::endl;
}
return 0;
}
#include <vector>
#include <string>
int main() {
std::vector<std::string> names = {"Alice", "Bob", "Charlie"};
// 使用 auto 自动推导类型
for(size_t i = 0; i < names.size(); ++i) {
auto& name = names[i]; // 推导为 std::string&
std::cout << "第 " << (i + 1) << " 个人: " << name << std::endl;
}
return 0;
}
运行结果预期:
第 1 个人: Alice 第 2 个人: Bob 第 3 个人: Charlie
代码解析:
auto& name = names[i]; 自动推导为 std::string&,可以直接修改元素。示例 4:operator[] 与 at() 的区别
对比 operator[] 和 at() 的行为差异。
实例
#include <iostream>
#include <vector>
#include <stdexcept>
int main() {
std::vector<int> numbers = {10, 20, 30};
// operator[] 不进行边界检查,越界访问后果自负
// 这里访问 numbers[5],但 size() 是 3,这是未定义行为
// 为了演示,我们只访问有效范围
std::cout << "operator[] 访问:" << std::endl;
for(size_t i = 0; i < 3; ++i) {
std::cout << "numbers[" << i << "] = " << numbers[i] << std::endl;
}
std::cout << "\nat() 访问(有边界检查):" << std::endl;
for(size_t i = 0; i < 3; ++i) {
std::cout << "numbers.at(" << i << ") = " << numbers.at(i) << std::endl;
}
std::cout << "\n建议:在确定索引不会越界时使用 operator[]," << std::endl;
std::cout << " 在不确定时使用 at() 以获得异常保护。" << std::endl;
return 0;
}
#include <vector>
#include <stdexcept>
int main() {
std::vector<int> numbers = {10, 20, 30};
// operator[] 不进行边界检查,越界访问后果自负
// 这里访问 numbers[5],但 size() 是 3,这是未定义行为
// 为了演示,我们只访问有效范围
std::cout << "operator[] 访问:" << std::endl;
for(size_t i = 0; i < 3; ++i) {
std::cout << "numbers[" << i << "] = " << numbers[i] << std::endl;
}
std::cout << "\nat() 访问(有边界检查):" << std::endl;
for(size_t i = 0; i < 3; ++i) {
std::cout << "numbers.at(" << i << ") = " << numbers.at(i) << std::endl;
}
std::cout << "\n建议:在确定索引不会越界时使用 operator[]," << std::endl;
std::cout << " 在不确定时使用 at() 以获得异常保护。" << std::endl;
return 0;
}
代码解析:
operator[]访问速度更快,因为不进行边界检查。at()更安全,但有异常处理的开销。- 选择建议:如果索引是确定安全的(如循环变量在 0 到 size()-1 之间),使用
operator[];如果索引来自外部输入或可能不确定,使用at()。
示例 5:计算向量点积
使用 operator[] 实现向量运算。
实例
#include <iostream>
#include <vector>
// 计算两个向量的点积
int dotProduct(const std::vector<int>& v1, const std::vector<int>& v2) {
int result = 0;
for(size_t i = 0; i < v1.size(); ++i) {
result += v1[i] * v2[i];
}
return result;
}
int main() {
std::vector<int> v1 = {1, 2, 3};
std::vector<int> v2 = {4, 5, 6};
int result = dotProduct(v1, v2);
std::cout << "向量 v1: ";
for(size_t i = 0; i < v1.size(); ++i) {
std::cout << v1[i] << " ";
}
std::cout << std::endl;
std::cout << "向量 v2: ";
for(size_t i = 0; i < v2.size(); ++i) {
std::cout << v2[i] << " ";
}
std::cout << std::endl;
std::cout << "点积: " << result << std::endl;
// 1*4 + 2*5 + 3*6 = 4 + 10 + 18 = 32
return 0;
}
#include <vector>
// 计算两个向量的点积
int dotProduct(const std::vector<int>& v1, const std::vector<int>& v2) {
int result = 0;
for(size_t i = 0; i < v1.size(); ++i) {
result += v1[i] * v2[i];
}
return result;
}
int main() {
std::vector<int> v1 = {1, 2, 3};
std::vector<int> v2 = {4, 5, 6};
int result = dotProduct(v1, v2);
std::cout << "向量 v1: ";
for(size_t i = 0; i < v1.size(); ++i) {
std::cout << v1[i] << " ";
}
std::cout << std::endl;
std::cout << "向量 v2: ";
for(size_t i = 0; i < v2.size(); ++i) {
std::cout << v2[i] << " ";
}
std::cout << std::endl;
std::cout << "点积: " << result << std::endl;
// 1*4 + 2*5 + 3*6 = 4 + 10 + 18 = 32
return 0;
}
运行结果预期:
向量 v1: 1 2 3 向量 v2: 4 5 6 点积: 32
代码解析:
- 使用
operator[]可以在算法中快速访问向量元素。 - 点积的计算就是对应位置元素相乘后求和。

C++ 容器类 <vector>