C ++ postfix increment operator implementation

I made the following example:

#include <iostream> #include <iterator> using namespace std; class myiterator : public iterator<input_iterator_tag, int> { int* p; public: myiterator(int* x) :p(x) {} myiterator(const myiterator& mit) : p(mit.p) {} myiterator& operator++() {++p;return *this;} myiterator& operator++(int) {myiterator tmp(*this); operator++(); return tmp;} bool operator==(const myiterator& rhs) {return p==rhs.p;} bool operator!=(const myiterator& rhs) {return p!=rhs.p;} int& operator*() {return *p;} }; int main () { int numbers[]={10,20,30,40,50}; myiterator beginning(numbers); myiterator end(numbers+5); for (myiterator it=beginning; it!=end; it++) cout << *it << " "; cout << endl; return 0; } 

from cplusplus.com/reference , and I get a compiler warning:

 iterator.cpp: In member function 'myiterator& myiterator::operator++(int)': iterator.cpp:13: warning: reference to local variable 'tmp' returned 

What is wrong here? The postfix signature is supposed to be myiterator operator++(int) i.e. return value?

Is any Postfix signature defined on STL iterators?

+4
source share
4 answers

Is any Postfix signature defined on STL iterators?

Standard.

The standard dictates such things. In the case of this operation, the standard basically says "you need to return something that can be converted to const X& ", where X is an iterator. In practice, this means that you can return by reference if this applies to you (this is not the case), or return by value.

See 24.1.3 / 1

+5
source

You do not want to return a link: in doing so, you return a link to a variable that, by the time the function returns, no longer exists. Anything you need:

 myiterator operator++(int) {myiterator tmp(*this); operator++(); return tmp;} 
+3
source

This line:

 myiterator& operator++(int) {myiterator tmp(*this); operator++(); return tmp;} 

Must be:

 myiterator operator++(int) {myiterator tmp(*this); operator++(); return tmp;} // ^^^^ Not return by reference. // Don't worry the cost is practically nothing for your class // And will probably be optimized into copying the pointer back. 

As a note:

You really don't need a copy constructor:

 myiterator(const myiterator& mit) : p(mit.p) {} 

The generated version of the compiler will work fine (since the three / four rule does not apply, since you do not own the RAW pointer contained in your class).

Your comparison operators should be marked as const, and I personally prefer to define the! = Operator in terms of the == operator and let the compiler optimize any inefficiency (although this is just a personal thing).

 bool operator==(const myiterator& rhs) const {return p==rhs.p;} bool operator!=(const myiterator& rhs) const {return !(*this == rhs);} // ^^^^^^^ Added const 

The * operator must have two versions. Normal and constant versions.

 int& operator*() {return *p;} int const& operator*() const {return *p;} 

As a final note: the pointer itself is an iterator. So in fact you don’t need to wrap pointers around to make them iterators, they will behave correctly as iterators (not just input iterators, but random access iterators).

+2
source

you return a reference to a variable that is destroyed when the method exits. the compiler warns you of the consequences of this. by the time the link is received by the caller, the variable it refers to no longer exists.

0
source

All Articles