自定义STL风格vector编译报错:lvalue required as increment operand
咱们来一步步拆解你遇到的这个编译错误:error: lvalue required as increment operand,搞清楚问题出在哪,以及怎么解决。
错误的核心原因
你当前的begin()成员函数返回的是原生指针类型的右值——也就是start这个成员指针的临时拷贝。而C++里的内置前置++运算符,必须作用于一个左值(能被修改、有内存地址的对象),因为它要直接操作变量本身的内容。
看你这段代码:
iterator begin() {return start;}
这里返回的是start的副本,是一个临时的指针对象(右值)。临时对象的生命周期极短,编译器不允许对它做修改操作,所以++(characters.begin())这种写法直接触发了报错。
为什么SGI STL能支持类似操作?
你提到看SGI STL没找到原因,其实核心区别是:SGI STL的迭代器是自定义类类型,而非原生指针。
对于自定义迭代器类来说,operator++()是类的成员函数,在C98及更早的标准里,成员函数默认可以在右值对象上调用(直到C11才引入了&限定符来限制)。而原生指针的++是内置运算符,严格要求操作数是左值,这就是两者的本质差异。
两种可行的解决办法
办法1:修改调用方式(最简单快速)
不要直接对begin()的返回值做前置++,先把迭代器赋值给一个左值变量再操作:
vector<char>::iterator it = characters.begin(); ++it; cout << *it << endl;
这样it是一个左值,++it完全符合编译器要求,代码可以正常编译运行。
办法2:实现自定义迭代器类(贴近STL的做法)
如果你想让++(characters.begin())这种写法合法,需要把iterator从原生指针改成自定义的迭代器类。比如:
template <class T> class vector_iterator { private: T* ptr; public: // 构造函数 vector_iterator(T* p = nullptr) : ptr(p) {} // 前置++:返回左值引用,支持链式操作 vector_iterator& operator++() { ++ptr; return *this; } // 后置++:返回右值,区分前置版本 vector_iterator operator++(int) { vector_iterator temp = *this; ++ptr; return temp; } // 解引用运算符 T& operator*() { return *ptr; } // 还可以按需实现其他必要运算符,比如->、==、!=等 };
然后在你的vector类里替换迭代器的定义:
template <class T, class alloc> class vector { public: typedef T value_type; typedef const value_type * const_iterator; typedef vector_iterator<T> iterator; // 替换为自定义迭代器 iterator start; iterator finish; iterator end_of_storage; iterator begin() {return start;} iterator end() {return finish;} // ... 其他成员函数需要适配这个自定义迭代器 };
这样++(characters.begin())就合法了:begin()返回的迭代器对象(右值)可以调用成员函数operator++(),并且返回的是左值引用,后续的解引用操作也能正常工作。
内容的提问来源于stack exchange,提问作者small bottle

