简体   繁体   中英

vector iterators c++

I am a little confused by the way begin and end work they seem to me to be inconsistant. When going forward and backwards they have different behaviors.

vector<Actor *> a;
a.push_back(new Actor(11));
a.push_back(new Actor(22));
a.push_back(new Actor(33));
vector<Actor *>::iterator it = a.begin();


int x  =0;
while(a.begin()+x != a.end()){
cout << (*(a.begin()+x)) << "\n";
x++;
}

cout << "\n";

int y = 1; // if this is set to 0 then its a seg fault =/ when I access 
while(a.end()-y != a.begin()){
cout << (*(a.end()-y)) << "\n";
y++;
}

Outputs

0x979a008
0x979a028
0x979a018


0
0x979a018
0x979a028

How can I get the expected pattern

0x979a008
0x979a028
0x979a018

0x979a018
0x979a028
0x979a008

You should use reverse iterators :

int y = 0;
while(a.rbegin() +y != a.rend()){
    cout << (*(a.rbegin()+y)) << "\n";
    y++;
}

Or even better would be to use the overloaded ++ operator of the iterators themselves:

auto iter = a.rbegin();
while(iter != a.rend()){
    cout << *(iter++) << "\n";
}

Note that begin() points to the first element of the vector, but end() points past the last element . It's never safe to dereference end() , but you can compare iterators to it.

If the vector is empty, then begin() == end() , and you may not dereference either one.

A more idiomatic way to loop over a vector's elements is:

for (vector<Actor*>::iterator i = a.begin(); i != a.end(); ++i) {
   // do something here
}

To iterate in reverse, it's simpler to use rbegin() and rend() , which work much the same way and begin() / end() , but iterate in reverse order:

for (vector<Actor*>::reverse_iterator i = a.rbegin(); i != a.rend(); ++i) {
   // do something here
}

Also, if you don't intend to modify the elements, you should use a const_iterator (or const_reverse_iterator instead.

One very simple way to achieve that would be following

// first element to the last
auto it = a.begin()
while (it != a.end())
{
cout<<*it<<"\n";
++it;
}
cout<<"\n"
// Last element to first
auto rit = a.rbegin()
while(rit != a.rend())
{
cout<<*rit<<"\n";
++rit;
}

NB: Do not try to dereference a.end() and beyond. When y = 0 in your program the a.end() is dereferenced in the line cout << (*(a.end()-y)) << "\\n"; This results in seg fault. Elements of vector are contained in a sequence which can be accessed from begin() through end()-1 . .end() points to one "past" the last element of the container and should not be dereferenced.

std::for_each(a.begin(), a.end(), [](const Actor *& a){ std::cout << a; });
std::for_each(a.rbegin(), a.rend(), [](const Actor *& a){ std::cout << a; });



auto print_actor = [](const Actor *& a){ std::cout << a; };
std::for_each(a.begin(), a.end(), print_actor);
std::for_each(a.rbegin(), a.rend(), print_actor);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM