How can I get a field from the last element of a vector in C++?
Asked Answered
A

8

90

I have a vector vec of structures. Such a structure has elements int a, int b, int c. I would like to assign to some int var the element c, from the last structure in a vector. Please can you provide me with this simple solution? I'm going circle in line like this:

var = vec.end().c;
Apron answered 11/1, 2013 at 9:38 Comment(3)
Duplicate of stackoverflow.com/questions/3651847Attractant
Just an another non-fancy way to do it: var=v[v.size() - 1]; Must check if vector is not empty.Antisyphilitic
*vec.rbegin()Partin
H
145

The immediate answer to your question as to fetching access to the last element in a vector can be accomplished using the back() member. Such as:

int var = vec.back().c;

Note: If there is a possibility your vector is empty, such a call to back() causes undefined behavior. In such cases you can check your vector's empty-state prior to using back() by using the empty() member:

if (!vec.empty())
   var = vec.back().c;

Likely one of these two methods will be applicable for your needs.

Heavyhanded answered 11/1, 2013 at 9:45 Comment(7)
Though, I can see a possiblity to satisfy both of us. You could just propose vec.back(), but explain to him that it only works for non-empty vectors and if he isn't sure about this state of the vector at this point of the code, a check for vec.empty() would be neccessary.Conduction
"three lines of code reminding someone non-native to standard containers..." - It doesn't remind him to think about indeterminate state, not if he is really a newbie. He'll just take that for granted and start to spam std::vector::emptys all over the place. Like said, the answer could be worded much more defensively. But Ok, it's your decision, granted.Conduction
@ChristianRau thats not the indeterminate state avoidance i was talking about. the var preinitialize was what I was referring to. And as I said, you may well be right that neither are warranted for participation in his final usage, but imho, both are warranted as a reminder to consider. Thats all, nothing beyond that.Heavyhanded
@Heavyhanded I understand that, but this is not a reminder, but a definite answer to his question. That is the only problem I have. It is good to teach such safety and cleannliness considerations to newbies, but likewise do you have to be especially careful to not indoctrinate them with dogmatic behaviour, but to think about the neccessity of such checks in each and every situation anew.Conduction
@ChristianRau Now that I actually buy into. I'm always looking to improve answer-skills, and when you put it like that, It makes much more sense to me. So the code isn't the problem, its the assumption its always the solution. I can agree that it could be seen as such, and should be better explained. I shall update the answer in due course.Heavyhanded
@ChristianRau ok then. updated. hope it is more compelling. I'm going to start backing out comments I don't think are contributory to the OP's question. Thank you for your patience.Heavyhanded
Much better. +1 for not proposing a crystal ball answer anymore. And +1 for providing additional information not immediately relevant for the question but improving the OP's overall awareness. ;)Conduction
E
21

vec.end() is an iterator which refers the after-the-end location in the vector. As such, you cannot deference it and access the member values. vec.end() iterator is always valid, even in an empty vector (in which case vec.end() == vec.begin())

If you want to access the last element of your vector use vec.back(), which returns a reference (and not iterator). Do note however that if the vector is empty, this will lead to an undefined behavior; most likely a crash.

Eichhorn answered 11/1, 2013 at 9:44 Comment(0)
C
10

Use back():

var = vec.back().c;
Cilium answered 11/1, 2013 at 9:40 Comment(0)
L
5

Try this: var = vec.back().c;

Also you may modify your code like:

var = vec.rbegin()->c;

In both versions first make sure that the vector is not empty!

Lindholm answered 11/1, 2013 at 9:41 Comment(4)
Nope; vec.end() is past the end, so *vec.end() is invalid.Xerophyte
No, dereferencing the end iterator is undefined behavior and not equivalent to back.Twit
Sorry typo. I meant rbegin()Lindholm
@ChristianRau I have edited my answer, please take another look at it. no need for prev simply use rbegin.Lindholm
X
2

var = vec.back().c; is what you want.

end() returns the iterator (not an element) past-the-end of the vector. back() returns a reference to the last element. It has a counterpart front() as well.

Xerophyte answered 11/1, 2013 at 9:40 Comment(0)
L
1

You can simply use back as it returns a reference to the last element.
var = vec.back().c

Liaoning answered 11/1, 2013 at 9:41 Comment(0)
S
0

You can use the std:vector<T>:back() function, e.g. vec.back().c. See http://www.cplusplus.com/reference/vector/vector/back/

Subscript answered 11/1, 2013 at 9:42 Comment(0)
G
0

The following code works for me.

int var;
var =  *(std::end(bar)-1);
std::cout<<var<<std::endl;
Gujarati answered 27/1, 2022 at 5:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.