STL中迭代器iterator与容器begin()方法的区别及代码行为疑问
#include <iostream> #include <vector> using namespace std; int main(void){ vector<int> v = {1, 2, 3}; auto& it = v.begin(); // 注:标准C++不支持将临时右值绑定到非常量左值引用,该写法依赖编译器扩展,标准写法为auto it = v.begin() // 1. v.begin() += 1; cout << *(v.begin()); // 输出1 // 2. cout << *(v.begin()+1); // 输出2 }
1. v.begin()属于左值还是右值?
标准容器的begin()成员函数返回值是迭代器临时对象,属于纯右值,没有固定的持久存储地址,表达式执行完成后就会被销毁。
2. 注释1和注释2的代码差异
- 注释1的
v.begin() += 1是对本次调用begin()生成的临时迭代器做偏移操作,操作完成后临时对象直接销毁,不会对后续v.begin()的调用结果产生任何影响。下一行再次调用v.begin()会重新生成指向容器首元素的新临时迭代器,解引用后输出为1。 - 注释2的
v.begin() + 1是直接使用本次调用begin()生成的临时迭代器做偏移,偏移后立刻解引用取值,不需要保留迭代器的修改状态,因此可以正确拿到第二个元素的值2。
3. 替换为迭代器it后两种写法均生效的原因
当操作对象替换为自定义的迭代器变量it时,it是有持久存储空间的左值:
- 执行
it += 1时,偏移操作会直接修改it本身存储的迭代器位置,修改结果会持久保留,后续解引用it即可得到偏移后的值2。 - 直接执行
*(it + 1)(it未被修改时初始指向首元素),是基于it当前的位置计算偏移结果,解引用后也能得到第二个元素的值2,不会出现临时迭代器修改失效的问题。
内容的提问来源于stack exchange,提问作者kims
相关产品推荐
相关产品推荐

