473,404 Members | 2,114 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,404 software developers and data experts.

STL question

Is there any way to use the STL algorithm for_each if my container
contains pointers? For example,

class A
{
int a;
virtual void print (void) {cout << a << endl;}
};
class B: public A
{
int b;
virtual void print (void) {cout << a << "," << b << endl;}
}

I want to have a list that I can call print() on for each member, so I
figured vector <A*>. Is there anyway to get the following with
for_each?

vector <A*>::iterator i;
for (i=list.begin(); i<list.end(); ++i) (*i)->print();

Russ
Jul 22 '05 #1
22 2188
"Rusty" <ru*****************@shaw.ca> wrote in message
news:b7********************************@4ax.com...
Is there any way to use the STL algorithm for_each if my container
contains pointers? For example,

class A
{
int a;
virtual void print (void) {cout << a << endl;}
};
class B: public A
{
int b;
virtual void print (void) {cout << a << "," << b << endl;}
}

I want to have a list that I can call print() on for each member, so I figured vector <A*>. Is there anyway to get the following with
for_each?


struct Printer : std::unary_function<A*, void> {
void operator() (A* a) const { /* write to cout */ }
}

std::for_each(list.begin(), list.end(), Printer());

HTH.

Jonathan
Jul 22 '05 #2
Rusty wrote:
Is there any way to use the STL algorithm for_each if my container
contains pointers? For example,

class A
{
int a;
virtual void print (void) {cout << a << endl;}
};
class B: public A
{
int b;
virtual void print (void) {cout << a << "," << b << endl;}
}

I want to have a list that I can call print() on for each member, so I
figured vector <A*>. Is there anyway to get the following with
for_each?
Sure..

struct call_print{
void operator()(A* a){ a->print(); }
};

and then

for_each(v.begin(), v.end(), call_print());

vector <A*>::iterator i;
for (i=list.begin(); i<list.end(); ++i) (*i)->print();
Don't call your vector 'list', there's already a std::list class.

Russ


Jul 22 '05 #3
Rusty <ru*****************@shaw.ca> wrote:
Is there any way to use the STL algorithm for_each if my container
contains pointers? For example,

class A
{
int a;
virtual void print (void) {cout << a << endl;}
};
class B: public A
{
int b;
virtual void print (void) {cout << a << "," << b << endl;}
}

I want to have a list that I can call print() on for each member, so I
figured vector <A*>. Is there anyway to get the following with
for_each?

vector <A*>::iterator i;
for (i=list.begin(); i<list.end(); ++i) (*i)->print();


for_each( vec.begin(), vec.end(), mem_fun( &A::print ) );
Jul 22 '05 #4
Daniel T. wrote:
vector <A*>::iterator i;
for (i=list.begin(); i<list.end(); ++i) (*i)->print();

for_each( vec.begin(), vec.end(), mem_fun( &A::print ) );


Hang on, it's a vector of pointers... Surely there's no way of getting
around the extra functor to dereference the pointer.

Jacques

Jul 22 '05 #5
In article <5V********************@news02.tsnz.net>,
ja*****@clawshrimp.com says...
Rusty wrote:
Is there any way to use the STL algorithm for_each if my container
contains pointers? For example,

class A
{
int a;
virtual void print (void) {cout << a << endl;}
};
class B: public A
{
int b;
virtual void print (void) {cout << a << "," << b << endl;}
}

I want to have a list that I can call print() on for each member, so I
figured vector <A*>. Is there anyway to get the following with
for_each?


Sure..

struct call_print{
void operator()(A* a){ a->print(); }
};


Using operator<< to do formatted printing of an object is a widely known
idiom, so it's probably better (at least IMO) to use it to do this job.
I'd change the definitions a little bit so the member functions take the
stream to write to as a parameter instead of always writing to
std::cout, and return the stream they're writing to.

class A
{
// I've defined it to take the ostream as a parameter instead of
// always writing to cout.
virtual std::ostream &print (std::ostream &os) const {return os<<a;}

// since we've defined print to be private, make operator<< a friend
// so it can call print.
friend std::ostream &operator<<(std::ostream &, A const *);
protected:
// a can't be private if you're going to access it directly in B
int a;
public:
A(int init) : a(init) {}
};

class B: public A
{
int b;
std::ostream &print(std::ostream &os) const {
return os << a << "," << b;
}
public:
B(int inita, int initb) : A(inita), b(initb) {}
};

and then add the definition of operator<<:

std::ostream &operator<<(std::ostream &os, A const *a) {
return a->print(os);
}

IMO, std::for_each isn't really the best tool for the job at hand
either. We're copying the contents of the vector to a stream, so
std::copy is really the algorithm for the job at hand:

std::ostream_iterator<A*> out(std::cout, "\n");
std::vector<A*> a;

// code to populate 'a' elided.

std::copy(a.begin(), a.end(), out);

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jul 22 '05 #6

"Jacques Labuschagne" <ja*****@clawshrimp.com> wrote in message
news:0c********************@news02.tsnz.net...
Daniel T. wrote:
vector <A*>::iterator i;
for (i=list.begin(); i<list.end(); ++i) (*i)->print();

for_each( vec.begin(), vec.end(), mem_fun( &A::print ) );


Hang on, it's a vector of pointers... Surely there's no way of

getting around the extra functor to dereference the pointer.

Jacques


mem_fun returns a function object taking a pointer argument, so this
should work. Of course, it only addresses the example, not the general
problem.

Jonathan
Jul 22 '05 #7
Jonathan Turkanis wrote:
mem_fun returns a function object taking a pointer argument, so this
should work. Of course, it only addresses the example, not the general
problem.


Right you are...

Thanks,
Jacques

Jul 22 '05 #8

"Rusty" <ru*****************@shaw.ca> wrote in message
news:b7********************************@4ax.com...
Is there any way to use the STL algorithm for_each if my container
contains pointers? For example,

class A
{
int a;
virtual void print (void) {cout << a << endl;}
};
class B: public A
{
int b;
virtual void print (void) {cout << a << "," << b << endl;}
}

I want to have a list that I can call print() on for each member, so I
figured vector <A*>. Is there anyway to get the following with
for_each?

vector <A*>::iterator i;
for (i=list.begin(); i<list.end(); ++i) (*i)->print();

Russ


Yes see code below:

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

class Print{
public:
void operator()(const int* i)
{
cout<< *i << '\n';
}
};

int main(){
Print print;
vector<int*,allocator<int> > intArr(3);
int x=1;
int y=2;
int z=3;
intArr[0] = &x;
intArr[1] = &y;
intArr[2] = &z;

for_each( intArr.begin(), intArr.end(), print);

return 0;
}
HTH.

Jul 22 '05 #9
Jacques Labuschagne <ja*****@clawshrimp.com> wrote:
Daniel T. wrote:
vector <A*>::iterator i;
for (i=list.begin(); i<list.end(); ++i) (*i)->print();

for_each( vec.begin(), vec.end(), mem_fun( &A::print ) );


Hang on, it's a vector of pointers... Surely there's no way of getting
around the extra functor to dereference the pointer.


mem_fun returns a functor that dereferences the pointer.
Jul 22 '05 #10
"Jonathan Turkanis" <te******@kangaroologic.com> wrote:
"Jacques Labuschagne" <ja*****@clawshrimp.com> wrote:
Daniel T. wrote:
>vector <A*>::iterator i;
>for (i=list.begin(); i<list.end(); ++i) (*i)->print();
for_each( vec.begin(), vec.end(), mem_fun( &A::print ) );
Hang on, it's a vector of pointers... Surely there's no way of

getting
around the extra functor to dereference the pointer.

Jacques


mem_fun returns a function object taking a pointer argument, so this
should work.


Of course it should work, this is exactly the type of problem that
mem_fun was designed to solve.

Of course, it only addresses the example, not the general
problem.
It does address the general problem which was (from the OP): Is there any way to use the STL algorithm for_each if my container
contains pointers?


The answer is, "Yes, one way is to use mem_fun."
Jul 22 '05 #11

"Daniel T." <po********@eathlink.net> wrote in message
news:po******************************@news02.east. earthlink.net...
"Jonathan Turkanis" <te******@kangaroologic.com> wrote:
"Jacques Labuschagne" <ja*****@clawshrimp.com> wrote:
Daniel T. wrote:
>>vector <A*>::iterator i;
>>for (i=list.begin(); i<list.end(); ++i) (*i)->print();
>
>
> for_each( vec.begin(), vec.end(), mem_fun( &A::print ) );

Hang on, it's a vector of pointers... Surely there's no way of getting
around the extra functor to dereference the pointer.

Jacques


mem_fun returns a function object taking a pointer argument, so this should work.


Of course it should work, this is exactly the type of problem that
mem_fun was designed to solve.


Would you feel better if I said 'does' instead of 'should'? I know it
works; it was a normative 'should'.
Of course, it only addresses the example, not the general
problem.


It does address the general problem which was (from the OP):
Is there any way to use the STL algorithm for_each if my container
contains pointers?


I don't we disagree about anything important. The more general problem
is how to iterate over a container of pointers when the operation you
wish to perform doesn't happen to be a member function.

Jonathan
Jul 22 '05 #12
On Sun, 18 Jan 2004 21:08:56 +0000, Rusty wrote:
Is there any way to use the STL algorithm for_each if my container
contains pointers? For example,

class A
{
int a;
virtual void print (void) {cout << a << endl;}
};
class B: public A
{
int b;
virtual void print (void) {cout << a << "," << b << endl;}
}

I want to have a list that I can call print() on for each member, so I
figured vector <A*>. Is there anyway to get the following with
for_each?

vector <A*>::iterator i;
for (i=list.begin(); i<list.end(); ++i) (*i)->print();

Russ


vector <A*>::iterator i;
for_each (list.begin(), list.end(), mem_fun(&A::print));

HTH,
M4

Jul 22 '05 #13
"Jonathan Turkanis" <te******@kangaroologic.com> wrote:
The more general problem
is how to iterate over a container of pointers when the operation you
wish to perform doesn't happen to be a member function.


That's easy too.

for_each( vec.begin(), vec.end(), myFunc );

for_each works fine with function pointers.

If the function happens to be in a different object. IE

class A { };
class B {
public:
void func( A* a );
};

vector<A*> vec;
B b;

Then one simply does this:

for_each( vec.begin(), vec.end(), bind1st( mem_fun(&B::func), &b ) );
Jul 22 '05 #14
"Daniel T." <po********@eathlink.net> wrote in message
news:po******************************@news02.east. earthlink.net...
"Jonathan Turkanis" <te******@kangaroologic.com> wrote:
The more general problem
is how to iterate over a container of pointers when the operation you wish to perform doesn't happen to be a member function.


That's easy too.

for_each( vec.begin(), vec.end(), myFunc );

for_each works fine with function pointers.


This is what I mentioned in my original post.

I know how to use the STL. What is your point?

Jonathan
Jul 22 '05 #15

"Rusty" <ru*****************@shaw.ca> wrote in message
news:b7********************************@4ax.com...
Is there any way to use the STL algorithm for_each if my container
contains pointers? For example,

class A
{
int a;
virtual void print (void) {cout << a << endl;}
};
class B: public A
{
int b;
virtual void print (void) {cout << a << "," << b << endl;}
}

I want to have a list that I can call print() on for each member, so I
figured vector <A*>. Is there anyway to get the following with
for_each?

vector <A*>::iterator i;
for (i=list.begin(); i<list.end(); ++i) (*i)->print();

Russ


I found I need to use:
for (i=list.begin(); i<list.end(); ++i) i[0]->print();

Although it looks like your only ever indexing the first element it's not ,
it works properly because your indexing the iterator and not the vector.

HTH
Jul 22 '05 #16

"Jumbo @uko2.co.uk>" <pcr1000011<nospam> wrote in message news:10***************@news.minx.net.uk...

vector <A*>::iterator i;
for (i=list.begin(); i<list.end(); ++i) (*i)->print();

Russ


I found I need to use:
for (i=list.begin(); i<list.end(); ++i) i[0]->print();

Although it looks like your only ever indexing the first element it's not ,
it works properly because your indexing the iterator and not the vector


It won't work properly if "list" is really a list and not a vector.
You're only guaranteed to be able to apply operator[] to random
access iterators.

His original code would have worked fine.

To get back to whether he could use for for_each. You could obviously define
your own functor for the third arg, but C++ provides an adapter already called
mem_fun

for_each(list.begin(), list.end(), mem_fun(&A::print));
Jul 22 '05 #17
On Sun, 18 Jan 2004 23:51:28 GMT, "Daniel T."
<po********@eathlink.net> wrote:

EXACTLY what I was after - thank you so much!

Russ
Rusty <ru*****************@shaw.ca> wrote:
Is there any way to use the STL algorithm for_each if my container
contains pointers? For example,

class A
{
int a;
virtual void print (void) {cout << a << endl;}
};
class B: public A
{
int b;
virtual void print (void) {cout << a << "," << b << endl;}
}

I want to have a list that I can call print() on for each member, so I
figured vector <A*>. Is there anyway to get the following with
for_each?

vector <A*>::iterator i;
for (i=list.begin(); i<list.end(); ++i) (*i)->print();


for_each( vec.begin(), vec.end(), mem_fun( &A::print ) );


Jul 22 '05 #18
Ron Natalie wrote:
You're only guaranteed to be able to apply operator[] to
random access iterators.


Does *(it + k) work with all iterators?
Thanks,
Martin
Jul 22 '05 #19

"Martin Eisenberg" <ma*****************@PAMudo.edu> wrote in message
news:10***************@ostenberg.wh.uni-dortmund.de...
Ron Natalie wrote:
You're only guaranteed to be able to apply operator[] to
random access iterators.


Does *(it + k) work with all iterators?


No. Here's a good summary of iterator requirements. It's not
authoritative (e.g., "trivial iterators" aren't mentioned in the
standard) but its pretty good.

Jonathan
Jul 22 '05 #20

"Jonathan Turkanis" <te******@kangaroologic.com> wrote in message
news:bu************@ID-216073.news.uni-berlin.de...

No. Here's a good summary of iterator requirements. It's not
authoritative (e.g., "trivial iterators" aren't mentioned in the
standard) but its pretty good.


Whoops! Omitted the link:

http://www.sgi.com/tech/stl/Iterators.html

Jonathan
Jul 22 '05 #21

"Martin Eisenberg" <ma*****************@PAMudo.edu> wrote in message news:10***************@ostenberg.wh.uni-dortmund.de...
Ron Natalie wrote:
You're only guaranteed to be able to apply operator[] to
random access iterators.


Does *(it + k) work with all iterators?


No, for other than random access iterators, you're limited bumping
it forward with ++. You can't add an arbitrary integer.

Jul 22 '05 #22

"Martin Eisenberg" <ma*****************@PAMudo.edu> wrote in message
news:10***************@ostenberg.wh.uni-dortmund.de...
Ron Natalie wrote:
You're only guaranteed to be able to apply operator[] to
random access iterators.


Does *(it + k) work with all iterators?


No, but "std::advance( it, k );" does. Note that it will modify "it".
std::advance is(usually) specialized for the various iterator categories,
using the most appropriate method to increment by k.

Jeff F
Jul 22 '05 #23

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

Similar topics

1
by: Mohammed Mazid | last post by:
Can anyone please help me on how to move to the next and previous question? Here is a snippet of my code: Private Sub cmdNext_Click() End Sub Private Sub cmdPrevious_Click() showrecord
3
by: Stevey | last post by:
I have the following XML file... <?xml version="1.0"?> <animals> <animal> <name>Tiger</name> <questions> <question index="0">true</question> <question index="1">true</question> </questions>
7
by: nospam | last post by:
Ok, 3rd or is it the 4th time I have asked this question on Partial Types, so, since it seems to me that Partial Types is still in the design or development stages at Microsoft, I am going to ask...
3
by: Ekqvist Marko | last post by:
Hi, I have one Access database table including questions and answers. Now I need to give answer id automatically to questionID column. But I don't know how it is best (fastest) to do? table...
10
by: glenn | last post by:
I am use to programming in php and the way session and post vars are past from fields on one page through to the post page automatically where I can get to their values easily to write to a...
10
by: Rider | last post by:
Hi, simple(?) question about asp.net configuration.. I've installed ASP.NET 2.0 QuickStart Sample successfully. But, When I'm first start application the follow message shown. ========= Server...
53
by: Jeff | last post by:
In the function below, can size ever be 0 (zero)? char *clc_strdup(const char * CLC_RESTRICT s) { size_t size; char *p; clc_assert_not_null(clc_strdup, s); size = strlen(s) + 1;
56
by: spibou | last post by:
In the statement "a *= expression" is expression assumed to be parenthesized ? For example if I write "a *= b+c" is this the same as "a = a * (b+c)" or "a = a * b+c" ?
2
by: Allan Ebdrup | last post by:
Hi, I'm trying to render a Matrix question in my ASP.Net 2.0 page, A matrix question is a question where you have several options that can all be rated according to several possible ratings (from...
3
by: Zhang Weiwu | last post by:
Hello! I wrote this: ..required-question p:after { content: "*"; } Corresponding HTML: <div class="required-question"><p>Question Text</p><input /></div> <div...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
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,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
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...
0
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...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
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...

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.