off_the_end iterator to vector::erase() function

S

subramanian100in

Consider
vector<string> v;

If we call,

v.erase(v.end())

this invokes undefined behaviour.

But, if we call

v.erase(v.begin(), v.end())
or
v.erase(v.end(), v.end())

will these last two calls invoke undefined behaviour ? Why I am asking
is that v.clear() on an empty vector is valid - it does nothing.
v.clear() is equivalent to v.erase(v.begin(), v.end()) which in turn
is equal to v.erase(v.end(), v.end()) when 'v' is empty. Am I
correct ?

Kindly clarify.

Thanks
V.Subramanian
 
M

moreshwardatye

My views. Guys, correct me if I am wrong.

~Moh

Consider
vector<string> v;

If we call,

v.erase(v.end())

this invokes undefined behaviour.
Correct. Reason: According to 23.1.1 point 3 and 4 operation erase is
defined on a vector(sequence in general) v as: v.erase(iter) where
iter is a valid de-referenceable iterator. Clearly, v.end() isn't.
But, if we call

v.erase(v.begin(), v.end())
or
v.erase(v.end(), v.end())

will these last two calls invoke undefined behaviour ?

First case will not be undefined as v.begin() and v.end() defines a
valid range. [I am not dereferencing the end element] this will in
fact return me a v.end()

Why I am asking
is that v.clear() on an empty vector is valid - it does nothing.
v.clear() is equivalent to v.erase(v.begin(), v.end()) which in turn
is equal to v.erase(v.end(), v.end()) when 'v' is empty. Am I
correct ?

this should be okay. according to 23.1 we see that begin() == end() in
case the sequence is empty and we are still providing a valid range.
 
A

Andrew Koenig

Consider
vector<string> v;

If we call,

v.erase(v.end())

this invokes undefined behaviour.
Correct.

But, if we call

v.erase(v.begin(), v.end())
or
v.erase(v.end(), v.end())

will these last two calls invoke undefined behaviour ?

No.

The difference is that when you call v.erase with one argument, you are
asking it to erase one element. In that case, you must specify a single
element to erase, and v.end() does not specify an element.

When you call v.erase with two arguments, you are asking it to erase all of
the elements in a range. In that case, you must specify a range, and
passing v.end() twice is one legitimate way of specifying a range that does
not contain any elements.
 
J

James Kanze

The difference is that when you call v.erase with one
argument, you are asking it to erase one element.

Couldn't one say that logically, "v.erase( i )" is the
equivalent of "v.erase( i, i + 1 )" (or whatever is necessary to
obtain an iterator one further in the container). In which
case, it's rather obvious why "v.erase( v.end() )" is illegal.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top