473,706 Members | 2,716 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

removing elements from vector<int> using <algorithm>

WANTED:

/* C++ Primer - 4/e
*
* Exercise: 9.26
* STATEMENT
* Using the following definition of ia, copy ia into a vector and
into a list. Use the single iterator form of erase to remove the
elements with odd values from your list * and the even values from your
vector.

int ia[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 55, 89 };
*
*/
WHAT I GET:

/home/arnuld/programming/c++ $ g++ -ansi -pedantic -Wall -Wextra
ex_09.26.cpp ex_09.26.cpp:

In function 'int main()': ex_09.26.cpp:43 :
error: '_1' was not declared in this scope /home/arnuld/programming/c++ $

CODE:

#include <iostream>
#include <vector>
#include <list>
#include <algorithm>
#include <iterator>
int main()
{
int ia[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 55, 89 };
const size_t ia_size = sizeof( ia ) / sizeof( *ia );

/* I made this array behave like a container:
"ia_begin" is the pointer to 1st element of ia
"ia_end" is the pointer to one past the last element of ia
*/
int *ia_begin = ia;
int *ia_end = ia + ia_size;

std::vector<int ivec;
std::list<int ilist;

/* copy elements from array to vector & list */
std::copy( ia_begin, ia_end, std::back_inser ter( ivec ) );
std::copy( ia_begin, ia_end, std::back_inser ter( ilist ) );
std::remove_if( ivec.begin(),
ivec.end(),
_1 % 2 == 0 );

/* print out the values */
std::copy( ivec.begin(), ivec.end(),
std::ostream_it erator<int(std: :cout, "\n" ) );

return 0;
}

I am just trying to use Lambda from Std. Lib. Why it is the problem ?

-- arnuld
http://lispmachine.wordpress.com

Oct 10 '07 #1
10 6065
"arnuld" <No****@NoPain. comwrote in message
news:pa******** *************** *****@NoPain.co m...
WANTED:

/* C++ Primer - 4/e
*
* Exercise: 9.26
* STATEMENT
* Using the following definition of ia, copy ia into a vector and
into a list. Use the single iterator form of erase to remove the
elements with odd values from your list * and the even values from your
vector.

int ia[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 55, 89 };
*
*/
WHAT I GET:

/home/arnuld/programming/c++ $ g++ -ansi -pedantic -Wall -Wextra
ex_09.26.cpp ex_09.26.cpp:

In function 'int main()': ex_09.26.cpp:43 :
error: '_1' was not declared in this scope /home/arnuld/programming/c++ $

CODE:

#include <iostream>
#include <vector>
#include <list>
#include <algorithm>
#include <iterator>
int main()
{
int ia[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 55, 89 };
const size_t ia_size = sizeof( ia ) / sizeof( *ia );

/* I made this array behave like a container:
"ia_begin" is the pointer to 1st element of ia
"ia_end" is the pointer to one past the last element of ia
*/
int *ia_begin = ia;
int *ia_end = ia + ia_size;

std::vector<int ivec;
std::list<int ilist;

/* copy elements from array to vector & list */
std::copy( ia_begin, ia_end, std::back_inser ter( ivec ) );
std::copy( ia_begin, ia_end, std::back_inser ter( ilist ) );
std::remove_if( ivec.begin(),
ivec.end(),
_1 % 2 == 0 );

/* print out the values */
std::copy( ivec.begin(), ivec.end(),
std::ostream_it erator<int(std: :cout, "\n" ) );

return 0;
}

I am just trying to use Lambda from Std. Lib. Why it is the problem ?
You might want to re-read your homework assignment again. "... Use the
single iterator form of erase to remove the elements..." I don't believe
std::remove_if qualifies as erase. I believe the instructor may be looking
for ivec.erase( iterator ); but this is just how I read it.
Oct 10 '07 #2
On 2007-10-10 09:34, arnuld wrote:
WANTED:

/* C++ Primer - 4/e
*
* Exercise: 9.26
* STATEMENT
* Using the following definition of ia, copy ia into a vector and
into a list. Use the single iterator form of erase to remove the
elements with odd values from your list * and the even values from your
vector.

int ia[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 55, 89 };
*
*/
WHAT I GET:

/home/arnuld/programming/c++ $ g++ -ansi -pedantic -Wall -Wextra
ex_09.26.cpp ex_09.26.cpp:

In function 'int main()': ex_09.26.cpp:43 :
error: '_1' was not declared in this scope /home/arnuld/programming/c++ $

CODE:

#include <iostream>
#include <vector>
#include <list>
#include <algorithm>
#include <iterator>
int main()
{
int ia[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 55, 89 };
const size_t ia_size = sizeof( ia ) / sizeof( *ia );

/* I made this array behave like a container:
"ia_begin" is the pointer to 1st element of ia
"ia_end" is the pointer to one past the last element of ia
*/
int *ia_begin = ia;
int *ia_end = ia + ia_size;

std::vector<int ivec;
std::list<int ilist;

/* copy elements from array to vector & list */
std::copy( ia_begin, ia_end, std::back_inser ter( ivec ) );
std::copy( ia_begin, ia_end, std::back_inser ter( ilist ) );
std::remove_if( ivec.begin(),
ivec.end(),
_1 % 2 == 0 );

/* print out the values */
std::copy( ivec.begin(), ivec.end(),
std::ostream_it erator<int(std: :cout, "\n" ) );

return 0;
}

I am just trying to use Lambda from Std. Lib. Why it is the problem ?
First, there is not lambda in the standard library (at least not yet,
they might add it in the next version) and second, you are trying to use
the boos lambda, but have not included any boost headers.

By the way, the assignment wants you to use erase() (not sure if they
meant std::erase or std::vector<T>: :erase(), I suspect the latter).

--
Erik Wikström
Oct 10 '07 #3
arnuld a écrit :
WANTED:

/* C++ Primer - 4/e
*
* Exercise: 9.26
* STATEMENT
* Using the following definition of ia, copy ia into a vector and
into a list. Use the single iterator form of erase to remove the
elements with odd values from your list * and the even values from your
vector.

int ia[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 55, 89 };
*
*/
WHAT I GET:

/home/arnuld/programming/c++ $ g++ -ansi -pedantic -Wall -Wextra
ex_09.26.cpp ex_09.26.cpp:

In function 'int main()': ex_09.26.cpp:43 :
error: '_1' was not declared in this scope /home/arnuld/programming/c++ $
[snip]
std::remove_if( ivec.begin(),
ivec.end(),
_1 % 2 == 0 );

[snip]

I am just trying to use Lambda from Std. Lib. Why it is the problem ?
There is no lambda in STL (for now).
Instead, you can use the std::modulus<fu nctor together with
std::bind2nd().

Michael
Oct 10 '07 #4
On Wed, 10 Oct 2007 08:07:23 +0000, Erik Wikström wrote:
First, there is not lambda in the standard library (at least not yet,
they might add it in the next version) and second, you are trying to use
the boos lambda, but have not included any boost headers.
OK, I will not use BOOST for now.

By the way, the assignment wants you to use erase() (not sure if they
meant std::erase or std::vector<T>: :erase(), I suspect the latter).
I tried it with vector's erase member function but that falls into the
infinite loop:
void rem_evens( std::vector<int >& ivec)
{
std::vector<int >::iterator begin = ivec.begin();
std::vector<int >::iterator end = ivec.end();

while( begin != end )
{
if( (*begin % 2) == 0 )
{
begin++ = ivec.erase( begin );
}
end = ivec.end();
}

}

int main()
{
int ia[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 55, 89 };
const size_t ia_size = sizeof( ia ) / sizeof( *ia );

int *ia_begin = ia;
int *ia_end = ia + ia_size;

std::vector<int ivec;
std::list<int ilist;

/* copy elements from array to vector & list */
std::copy( ia_begin, ia_end, std::back_inser ter( ivec ) );
std::copy( ia_begin, ia_end, std::back_inser ter( ilist ) );

/* vector before values are removed */
std::copy( ivec.begin(), ivec.end(),
std::ostream_it erator<int>( std::cout, "\n" ) );
rem_evens( ivec );

/* vector after even values are removed */
std::copy( ivec.begin(), ivec.end(),
std::ostream_it erator<int>( std::cout, "\n" ) );

return 0;
}


-- arnuld
http://lispmachine.wordpress.com

Oct 10 '07 #5
On Wed, 10 Oct 2007 02:38:10 -0700, James Kanze wrote:
I'm not sure what this statement is supposed to do, but it
looks very, very wrong (and may not compile with some
implementations ).

Note that the statement has a very different meaning
depending on whether vector<>::itera tor is a typedef for a
pointer, or is a class type. Since the code shouldn't
compile if it is a typedef for a pointer, I will assume that
it is a class type,
yes, it is a class because VECTOR is a class and erase is its memebr
function.

which means that you have the equivalent of:
begin.operator+ +( 0 ).operator=( ivec.erase( begin ) ) ;
I dont' know and don't understand what that

begin.operator+ +( 0 ).operator

means :-(
while ( begin != end ) {
if ( condition ) {
begin = vec.erase( begin ) ;
} else {
++ begin ;
}
}
}
You either increment, or you use the iterator returned by erase.
OK ,i got it but since we have removed the element, so the ivec.end()
iterator defined previously (before erasing) must invalidate but it does
not whereas insert() invalidates such things . I don't understand the
phenomenon.

Of course, the classical idiom would use remove here:

vec.erase(
remove_if( vec.begin(), vec.end(), condition ), vec.end() ) ;


Aha... that's good :-) but that's new to me. so this member function takes
2 arguments:

ivec.erase( algorithm, end_iterator )

it is mysterious, why it takes end_iterator here. I need to look up the
that ERASE member function in Stroustrup .


-- arnuld
http://lispmachine.wordpress.com

Oct 10 '07 #6
Michael DOUBEZ wrote:
arnuld a écrit :
>WANTED:
/* C++ Primer - 4/e
*
* Exercise: 9.26
* STATEMENT
* Using the following definition of ia, copy ia into a vector and
into a list. Use the single iterator form of erase to remove the
elements with odd values from your list * and the even values from your
vector.
int ia[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 55, 89 };
*
*/
WHAT I GET:

/home/arnuld/programming/c++ $ g++ -ansi -pedantic -Wall -Wextra
ex_09.26.cpp ex_09.26.cpp:
In function 'int main()': ex_09.26.cpp:43 :
error: '_1' was not declared in this scope
/home/arnuld/programming/c++ $ [snip]
std::remove_if( ivec.begin(), ivec.end(),
_1 % 2 == 0 );
[snip]

I am just trying to use Lambda from Std. Lib. Why it is the problem ?

There is no lambda in STL (for now).
Instead, you can use the std::modulus<fu nctor together with
std::bind2nd().
std::not2 is also needed, the Predicate looks like:
bind2nd(not2(mo dulus<int>()), 2))
Oct 10 '07 #7
arnuld wrote:
>On Wed, 10 Oct 2007 02:38:10 -0700, James Kanze wrote:
>I'm not sure what this statement is supposed to do, but it
looks very, very wrong (and may not compile with some
implementation s).

Note that the statement has a very different meaning
depending on whether vector<>::itera tor is a typedef for a
pointer, or is a class type. Since the code shouldn't
compile if it is a typedef for a pointer, I will assume that
it is a class type,

yes, it is a class because VECTOR is a class and erase is its memebr
function.

>which means that you have the equivalent of:
> begin.operator+ +( 0 ).operator=( ivec.erase( begin ) ) ;

I dont' know and don't understand what that

begin.operator+ +( 0 ).operator

means :-(
> while ( begin != end ) {
if ( condition ) {
begin = vec.erase( begin ) ;
} else {
++ begin ;
}
}
}
You either increment, or you use the iterator returned by erase.

OK ,i got it but since we have removed the element, so the ivec.end()
iterator defined previously (before erasing) must invalidate but it does
not whereas insert() invalidates such things . I don't understand the
phenomenon.

>Of course, the classical idiom would use remove here:

vec.erase(
remove_if( vec.begin(), vec.end(), condition ), vec.end() ) ;

Aha... that's good :-) but that's new to me. so this member function takes
2 arguments:

ivec.erase( algorithm, end_iterator )

it is mysterious, why it takes end_iterator here. I need to look up the
that ERASE member function in Stroustrup .
template < class ForwardIterator , class Predicate >
ForwardIterator remove_if ( ForwardIterator first,
ForwardIterator last,
Predicate pred )
{
ForwardIterator result = first;
for ( ; first != last; ++first)
if (!pred(*first)) *result++ = *first;
return result;
}

actually remove_if does NOT remove any thing, it just move the matched
items forward to overwrite those are not.
std::vector<int >::iterator pos
= remove_if(ivec. .begin(), ivec.end(),
std::bind2nd(st d::not2(std::mo dulus<int>()), 2));

now, pos points to the first item that's not matched

iterator vector::erase (iterator first, iterator last);

ivec.erase(pos, ivec.end());

now it's clear that, vector::erase erases a iterator range


Oct 10 '07 #8
arnuld wrote:
>On Wed, 10 Oct 2007 02:38:10 -0700, James Kanze wrote:
>I'm not sure what this statement is supposed to do, but it
looks very, very wrong (and may not compile with some
implementation s).

Note that the statement has a very different meaning
depending on whether vector<>::itera tor is a typedef for a
pointer, or is a class type. Since the code shouldn't
compile if it is a typedef for a pointer, I will assume that
it is a class type,

yes, it is a class because VECTOR is a class and erase is its memebr
function.

>which means that you have the equivalent of:
> begin.operator+ +( 0 ).operator=( ivec.erase( begin ) ) ;

I dont' know and don't understand what that

begin.operator+ +( 0 ).operator

means :-(

means that you can't increment rvalue return by a function.

int f() { return 10; }
++f(); //modifying an rvalue is illformed

But VC has an extension to compile the code. you can turn it off by /Za
Oct 10 '07 #9
arnuld wrote:
On Wed, 10 Oct 2007 02:38:10 -0700, James Kanze wrote:
I'm not sure what this statement is supposed to do, but it
looks very, very wrong (and may not compile with some
implementations ).
Note that the statement has a very different meaning
depending on whether vector<>::itera tor is a typedef for a
pointer, or is a class type. Since the code shouldn't
compile if it is a typedef for a pointer, I will assume that
it is a class type,
yes, it is a class because VECTOR is a class and erase is its memebr
function.
vector<>::itera tor can be a class type, but it can also be a
typedef to a pointer. In most of the early implementations , it
was just a typedef to a pointer.
which means that you have the equivalent of:
begin.operator+ +( 0 ).operator=( ivec.erase( begin ) ) ;
I dont' know and don't understand what that
begin.operator+ +( 0 ).operator
means :-(
It's the function which overloads of the ++ operator. For
overloaded operators, the name of the function which overloads
the operator is "operator <op>", where <opis the operator
being overloaded.

++ and -- are a bit special, as well, since there are two
versions, one for prefix, and one for postfix. For whatever
reasons, the postfix version takes an additional int argument;
the compiler passes it 0 when it is being called using the
normal operator syntax.
while ( begin != end ) {
if ( condition ) {
begin = vec.erase( begin ) ;
} else {
++ begin ;
}
}
You either increment, or you use the iterator returned by erase.
OK ,i got it but since we have removed the element, so the ivec.end()
iterator defined previously (before erasing) must invalidate but it does
not whereas insert() invalidates such things. I don't understand the
phenomenon.
Erase on a vector invalidates all iterators which designate the
element, or follow it. But you're right that that includes the
end iterator, so the loop should read:

while ( begin != vec.end() ) ...

If you're erasing in the loop, you can't cache the end()
iterator.
Of course, the classical idiom would use remove here:
vec.erase(
remove_if( vec.begin(), vec.end(), condition ), vec.end() ) ;
Aha... that's good :-) but that's new to me. so this member function takes
2 arguments:
ivec.erase( algorithm, end_iterator )
vector::erase() has two overloads: one takes a single iterator,
and removes just that element; the other takes two iterators,
which define a sequence of elements to be removed.

The algorithm remove_if returns an iterator. You should read
the specifications of the function.
it is mysterious, why it takes end_iterator here. I need to
look up the that ERASE member function in Stroustrup .
You need to look up all of the overloads to erase, and you need
to look up the algorithm remove/remove_if: because of the fact
that (like all of the algorithms), they take iterators, and not
containers, they can't actually remove anything. So all they do
is regroup the elements which aren't removed at the front of the
sequence, and return an iterator to the first element which
follows. This is used, with the end iterator, as an argument to
the erase function, which does the actual removal.

--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Oct 10 '07 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

12
5061
by: Gaurav | last post by:
Hello I have a program that basically inverts the contents of files except first line. It compiles fine but gives me core dump on running. If i comment temp.clear() it runs fine, but i need it to clear the temp vector for each file. ********************* code *******************
3
5812
by: Andreas Krueger | last post by:
Hi! I am fed up with vector<int> iv; iv.push_back(42); iv.push_back(9); iv.push_back(11); ... and would rather use a function "fillVector": vector<int> iv = fillVector(42,9,11); like in Mathematica(tm): someList={42,9,11};
20
17823
by: Anonymous | last post by:
Is there a non-brute force method of doing this? transform() looked likely but had no predefined function object. std::vector<double> src; std::vector<int> dest; std::vector<double>::size_type size = src.size(); dest.reserve(size); for (std::vector<int>::size_type i = 0;
5
4320
by: google | last post by:
Hi All, I'm just getting started learning to use <algorithm> instead of loads of little for loops, and I'm looking for a bit of advice/mentoring re: implementing the following... I have a vector of boost::shared_ptr's, some of which may be NULL. I'd like to find out if there are any non-NULL elements in the vector. Here's what I have at the moment.
2
7278
by: subramanian100in | last post by:
Consider the following piece of code: #include <iostream> #include <fstream> #include <vector> #include <string> #include <utility> #include <iterator> #include <algorithm> int main()
10
5014
by: arnuld | last post by:
It is quite an ugly hack but it is all I am able to come up with for now :-( and it does the requires work. I want to improve the program, I know you people have much better ideas ;-) /* C++ Primer - 4/e * * exercise 9.20 * STATEMENT: * Write a program to to compare whether a vector<intcontains the
5
6048
by: jeremit0 | last post by:
I'm trying to sort a vector<complex<double and can't figure it out. I recognize the problem is that there isn't a default operator< for complex data types. I have written my own operator and can use it, but std::sort doesn't seem to find it. I have copied a very simple example below. Everything compiles just fine when the line with std::sort function is commented out, but with that line included a whole slew of errors are given like: ...
3
4341
by: silverburgh.meryl | last post by:
Hi, Is there a STL algorithm to compare if 2 vector<inthave same values? Thank you.
42
4528
by: barcaroller | last post by:
In the boost::program_options tutorial, the author included the following code: cout << "Input files are: " << vm.as< vector<string() << "\n"; Basically, he is trying to print a vector of string, in one line. I could
0
8773
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9276
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9145
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
8983
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
6613
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5935
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4442
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4705
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
2495
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.