Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > proper way to delete elements from a vector

Reply
Thread Tools

proper way to delete elements from a vector

 
 
cayblood
Guest
Posts: n/a
 
      11-03-2005
I want to iterate through a vector and erase elements that meet a
certain criteria. I know there is an algorithmic way of doing this,
but first I would like to know how to do it with normal iteration. I'm
am trying to do something like:

vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);

for (vector<int>::iterator iter = v.begin();
iter != v.end();
++iter)
{
if (*iter > 2) iter = v.erase(iter);
}


This is giving me an error saying: error: void value not ignored as it
ought to be. I'm sure what I'm doing is wrong, but I can't find a good
example of the right way to do this.

Thanks,
Carl

 
Reply With Quote
 
 
 
 
Grahamo@nospam.com
Guest
Posts: n/a
 
      11-03-2005
have a look at this line........


iter = v.erase(iter);


can you see anything wrong with it?

G

 
Reply With Quote
 
 
 
 
Clark S. Cox III
Guest
Posts: n/a
 
      11-03-2005
On 2005-11-03 06:09:32 -0500, "(E-Mail Removed)"
<(E-Mail Removed)> said:

> have a look at this line........
>
> iter = v.erase(iter);
>
> can you see anything wrong with it?


No, what do you think is wrong with it?

--
Clark S. Cox, III
http://www.velocityreviews.com/forums/(E-Mail Removed)

 
Reply With Quote
 
peter koch
Guest
Posts: n/a
 
      11-03-2005

cayblood skrev:

> I want to iterate through a vector and erase elements that meet a
> certain criteria. I know there is an algorithmic way of doing this,
> but first I would like to know how to do it with normal iteration. I'm
> am trying to do something like:
>
> vector<int> v;
> v.push_back(1);
> v.push_back(2);
> v.push_back(3);
> v.push_back(4);
>
> for (vector<int>::iterator iter = v.begin();
> iter != v.end();
> ++iter)
> {
> if (*iter > 2) iter = v.erase(iter);
> }
>
>
> This is giving me an error saying: error: void value not ignored as it
> ought to be. I'm sure what I'm doing is wrong, but I can't find a good
> example of the right way to do this


Use the standard library for this:

std::erase(std::remove_if(v.begin(),v.end(),pred), v.end());

where pred is the predicate (designating the elements you want to
erase).
If you use boost::lambda, pred is as simple as _1 > 2. Otherwise you'll
have to use bind and std::greater (if i remember correctly) or write
your own predicate:

struct predicate
{
predicate(int val): val_(val) {}
bool operator<(int i) { return i > val_; }
private:
int val_;
};

and call it like this:
std::erase(std::remove_if(v.begin(),v.end(),predic ate(2)),v.end());

In real code, predicate should be renamed to e.g. less_than.
Perhaps there is already some std support for this.

/Peter
>
> Thanks,
> Carl


 
Reply With Quote
 
Valentin.Samko
Guest
Posts: n/a
 
      11-03-2005
> This is giving me an error saying: error: void value not ignored as it
> ought to be. I'm sure what I'm doing is wrong, but I can't find a good
> example of the right way to do this.


Which compiler are you using? I do not see any technical errors in your
code.

--

Valentin Samko - http://www.valentinsamko.com

 
Reply With Quote
 
werasm
Guest
Posts: n/a
 
      11-03-2005

cayblood wrote:
> I want to iterate through a vector and erase elements that meet a
> certain criteria. I know there is an algorithmic way of doing this,
> but first I would like to know how to do it with normal iteration. I'm
> am trying to do something like:
>
> vector<int> v;
> v.push_back(1);
> v.push_back(2);
> v.push_back(3);
> v.push_back(4);
>
> for (vector<int>::iterator iter = v.begin();
> iter != v.end();
> ++iter)
> {
> if (*iter > 2) iter = v.erase(iter);
> }


You forgot to qualify vector with std. vector exists in the standard
namespace. The following code was compiled with VC7.1. It is almost
exactly yours, apart from me qualifying vector with std. Note also the
algorthmic way. Your way was commented out, but does the same thing -
BTW, you had an error in your code. When an item is erased, the
following item remained because you should conditionally increment...

Here goes:

// CompileTest.cpp : Defines the entry point for the console
application.
//
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>

template<class T>
struct print
{
void operator()( const T& t )
{
std::cout << t << std::endl;
}
};

int main(int argc, char* argv[])
{
typedef std::vector<int> ivect;
ivect v;

v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);


//for( ivect::iterator iter = v.begin(); iter != v.end(); )
//{
// if (*iter > 2) iter = v.erase(iter);
// else ++iter;
//}
v.erase( std::remove_if( v.begin(), v.end(), std::bind2nd(
std::greater<int>(), 2 ) ), v.end() );

std::for_each( v.begin(), v.end(), print<int>() );

return 0;
}

Regards,

Werner

 
Reply With Quote
 
werasm
Guest
Posts: n/a
 
      11-03-2005

(E-Mail Removed) wrote:
> have a look at this line........
>
>
> iter = v.erase(iter);
>
>
> can you see anything wrong with it?


Hmmm, me neither.

>
> G


 
Reply With Quote
 
werasm
Guest
Posts: n/a
 
      11-03-2005
v.erase( std::remove_if( v.begin(), v.end(), std::bind2nd(
> std::greater<int>(), 2 ) ), v.end() );
>
> std::for_each( v.begin(), v.end(), print<int>() );


The for_each could be replaced by:

std::copy( v.begin(), v.end(), std:stream_iterator<int>(std::cout) );

The only difference is that this streams the data to std output
sequentially without cr/linefeed.

Regards,

W

 
Reply With Quote
 
Grahamo@nospam.com
Guest
Posts: n/a
 
      11-03-2005
apologies.... should have checked the return value from erase. My
mistake. It would have been a runtime error not acompile error in any
case G

 
Reply With Quote
 
Neil Cerutti
Guest
Posts: n/a
 
      11-03-2005
On 2005-11-03, cayblood <(E-Mail Removed)> wrote:
> I want to iterate through a vector and erase elements that meet
> a certain criteria. I know there is an algorithmic way of
> doing this, but first I would like to know how to do it with
> normal iteration. I'm am trying to do something like:
>
> vector<int> v;
> v.push_back(1);
> v.push_back(2);
> v.push_back(3);
> v.push_back(4);
>
> for (vector<int>::iterator iter = v.begin();
> iter != v.end();
> ++iter)
> {
> if (*iter > 2) iter = v.erase(iter);
> }


vector<T>::erase returns an interator to the next element in the
vector, so in that case you mustn't increment iter.

> This is giving me an error saying: error: void value not
> ignored as it ought to be.


The code you posted doesn't seem to have that error. Post actual
code whenever possible. If it's an except, make it a complete and
compilable excerpt.

Here's one example of using erase in a loop:

for (vector<int>::iterator i = v.begin(); i != v.end(); /* */)
{
if (*i > 2) {
i = v.erase(i);
} else {
++i;
}
}

Using the standard functions remove_if and erase (as shown in
another post) will be better in most cases.

Note that remove_if does not actually erase elements. It swaps
elements that must be retained to the front of the container and
returns an iterator to the end of the swapped elements. So it's
usually combined with erase.

Assuming v is (1, 2, 3, 4), as above:

vector<int>::iterator i = remove_if(v.begin(), v.end(),
bind2nd(greater<int>(), 2));

If the standard functions objects are a mystery, you may define a
function instead.

bool greater_than_2(int i)
{
return i > 2;
}

vector<int>::iterator i = remove_if(v.begin(), v.end(), greater_than_2);

After either of those remove_if calls, v contains (1, 2, 3, 4).

Since the retained alements were already in front, nothing
happened. However, i now points to 3, and you can erase from
there to v.end() to get your final answer.

v.erase(i, v.end());

As shown in another poset, a popular idiom is to combine the
calls into one line, eliminating the temporary iterator.

v.erase(remove_if(v.begin(), v.end(), bind2nd(greater<int>(), 2))
, v.end());

--
Neil Cerutti
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Proper way to delete/kill a logger? cassiope Python 4 11-28-2011 04:27 PM
const vector<A> vs vector<const A> vs const vector<const A> Javier C++ 2 09-04-2007 08:46 PM
Initializing vector<vector<int> > and other vector questions... pmatos C++ 6 04-26-2007 05:39 PM
Free memory allocate by a STL vector, vector of vector, map of vector Allerdyce.John@gmail.com C++ 8 02-18-2006 12:48 AM
XSD - proper way to express group of elements... unishippers.suckfeed.newshosting.com XML 1 11-04-2004 12:36 PM



Advertisments