11

I am a new C++ learner, and I read a code block about C++ STL accessing the last element from a vector.

Why does the code at line 6, 7, and 8 need to subtract 1 to be equal to that at line 5?

1.    std::vector<int> v;
2.    v.push_back(999);
3.    //fill up the vector
4.    //...

5.    int j = v.back();
6.    int j = v.[size-1]
7.    int j = v.at(v.size()-1)
8.    int j = *(v.end()-1)
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ning Chang
  • 233
  • 1
  • 2
  • 7

7 Answers7

26

Here's an illustration of which is which

v: [ 1 | 2 | 3 | 4 | ... | 999 ]
                                
   front()                back() end()
     
   begin()

where front() and back() return a (const) reference to the first and last element respectively, and end() returns an iterator (sort of a pointer) to one beyond the last element of vector. begin() returns an iterator to the first element of a vector.

These are also explained at std::vector

front access the first element
back access the last element
end/cend returns an iterator to the end
begin/cbegin returns an iterator to the beginning


Typically, you start counting at one. This is different in C or C++, where an index into an array or a sequence starts at zero. This is the reason, why you must subtract one from size. This means, in order to access the first element of an array, or in this case of a vector, you say

v[0]

and not

v[1]

Equally for the last (nth) element, you wouldn't take size or n of an array (a vector), but rather one less, e.g.

v[size() - 1]

or

v[n - 1]
Olaf Dietsche
  • 72,253
  • 8
  • 102
  • 198
12
5. int j = v.back();

std::vector::back is defined to return the last element in the vector. This is straight forward.

7. int j = v.[size-1]

Indices are 0 based in c++. If a sequential container has N elements, the valid indices are between 0 and N-1 inclusively. The last element is therefor N-1, or size()-1.

8. int j = *(v.end()-1)

std::vector::end returns an iterators to one-past-the-end of the container. The element just before is then the last element in the vector.

François Andrieux
  • 28,148
  • 6
  • 56
  • 87
3

To answer your title question:

The function calls begin(), end() will return a iterator position. back() simply returns the last element in the Vector. Usually begin() and end() are used this way.

vector<int>::iterator i = someVector.begin();  //or someVector.end();
while(i != someVector.end()){
    //do something;
    i++;
}  //this will loop through all elements in the vector;

As others have mentioned, .end() is 1 position after the last element. The distance depends on data structure implementation and data types. In your case, you can even consider the iterator as a pointer pointing to a int. (but they are not!!!) So if you dereference it it will give you a value. In fact, `

someVector.back();

is the same as

*(someVector.end()-1);

To answer your content question: we start counting from 0 as @FrankS101 stated.

L. Dai
  • 229
  • 2
  • 13
2

vector.end() - Returns an iterator referring to the past-the-end element in the vector container. vector.back() - Returns a reference to the last element in the vector.

Marek Vitek
  • 1,573
  • 9
  • 20
1

From cplusplus:

back() returns a reference to the last element in the vector.

Unlike member vector::end, which returns an iterator just past this element, this function returns a direct reference.

Calling this function on an empty container causes undefined behavior.

Aakash Verma
  • 3,705
  • 5
  • 29
  • 66
  • cplusplus is a poor reference, it is not always accurate. Please prefer http://en.cppreference.com – François Andrieux Jun 29 '17 at 17:50
  • 1
    But has way better examples. What exactly have you found there inaccurate? – Marek Vitek Jun 29 '17 at 17:53
  • Yea, I;d not exactly used the word 'poor' even if I had to. – Aakash Verma Jun 29 '17 at 17:54
  • @MarekVitek I refer you here: [What's wrong with cplusplus.com?](https://stackoverflow.com/questions/6520052/whats-wrong-with-cplusplus-com) cplusplus and cppreference have different target audiences. cplusplus.com trades accuracy for a lower bar to entry. Good for a quick read, but if you really need to know the details, look elsewhere. – user4581301 Jun 29 '17 at 18:03
  • 2
    @user4581301 Just seeing last edit on std::move on cppreference.com makes me feel, they are no different. There is just nobody with need to write about it on SO. If I would really solid information, then I will turn to standard itself. For beginners is cplusplus.com just fine. And if you spot an errror, you can fix it. – Marek Vitek Jun 29 '17 at 18:21
  • Bingo on the Standard. Thing is the Standard's barrier to entry is even higher than cppreference's. Any attempt at interpreting the source document to reduce the complexity will introduce errors and expose differences in interpretation. – user4581301 Jun 29 '17 at 18:33
0

std::vector::end() is one beyond the iterator that comprises std::vector::back().

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
-1

back() just returns a reference to the last element. while end() returns a pointer or an iterator to the last element. Also, end() can be used to check the stopping condition when iteration is performed from the beginning using begin().

Parveen Kumar
  • 175
  • 3
  • 5