By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,454 Members | 3,191 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,454 IT Pros & Developers. It's quick & easy.

How to use a class's member function in STL's algorithm?

P: n/a
We know that alomost every algorithm function, such as for_each,
find_if, use funcional as well as function pointer. But when I want
to use another class's member function, how could I do?

See example:
class TestPrint
{
public:
TestPrint( int i ) { start_num = i; }
void print( int i )
{
cout << endl<< "| " << i + start_num <<
" |" << endl;
}
private:
int start_num;
};

int main()
{
TestPrint* pTest = new TestPrint( 8 );
int a[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
for_each( a, a + 9, /*** Use the pTest's "print" ***/ );
delete pTest;
return 0;
}

/*** Use the pTest's "print" ***/ is where I want to write code .
Jul 12 '08 #1
Share this Question
Share on Google+
9 Replies


P: n/a
On Jul 12, 4:54*pm, "want.to.be.professer" <guolihui...@gmail.com>
wrote:
We know that alomost every algorithm function, such as for_each,
find_if, *use funcional as well as function pointer. But when I want
to use another class's member function, how could I do?

See example:

class TestPrint
{
public:
* * * * TestPrint( int i ) { start_num = i; }
* * * * void print( int i )
* * * * {
* * * * * * * * cout << endl<< "| * * * *" << i +start_num <<
" * * * * * * * *|" << endl;
* * * * }
private:
* * * * int start_num;

};

int main()
{
* * * * TestPrint* pTest = new TestPrint( 8 );
* * * * int *a[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
* * * * for_each( a, a + 9, /*** Use the pTest's "print" ***/ );
* * * * delete pTest;
* * * * return 0;

}

/*** Use the pTest's "print" ***/ is where I want to write code .
sorry
for_each( a, a + 9, /*** Use the pTest's "print" ***/ );
should be
for_each( a, a + 10, /*** Use the pTest's "print" ***/ );
Jul 12 '08 #2

P: n/a
On Jul 12, 1:59*pm, "want.to.be.professer" <guolihui...@gmail.com>
wrote:
On Jul 12, 4:54*pm, "want.to.be.professer" <guolihui...@gmail.com>
wrote:
We know that alomost every algorithm function, such as for_each,
find_if, *use funcional as well as function pointer. But when I want
to use another class's member function, how could I do?
See example:
class TestPrint
{
public:
* * * * TestPrint( int i ) { start_num = i; }
* * * * void print( int i )
* * * * {
* * * * * * * * cout << endl<< "| * * * *" << i+ start_num <<
" * * * * * * * *|" << endl;
* * * * }
private:
* * * * int start_num;
};
int main()
{
* * * * TestPrint* pTest = new TestPrint( 8 );
* * * * int *a[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
* * * * for_each( a, a + 9, /*** Use the pTest's "print" ***/ );
* * * * delete pTest;
* * * * return 0;
}
/*** Use the pTest's "print" ***/ is where I want to write code .

sorry
* * * * for_each( a, a + 9, /*** Use the pTest's "print" ***/ );
should be
* * * * for_each( a, a + 10, /*** Use the pTest's "print" ***/ );
You can use binders like boost::bind, or standard binders like bind1st
(here) / bind2nd along with std::mem_fun_ref.

for_each( a, a + 9, bind(&TestPrint::print, pTest, _1));

Make the print member a const member function, else std:: binders
won't probably work.
Jul 12 '08 #3

P: n/a
On Jul 12, 5:26*pm, Abhishek Padmanabh <abhishek.padman...@gmail.com>
wrote:
On Jul 12, 1:59*pm, "want.to.be.professer" <guolihui...@gmail.com>
wrote:
On Jul 12, 4:54*pm, "want.to.be.professer" <guolihui...@gmail.com>
wrote:
We know that alomost every algorithm function, such as for_each,
find_if, *use funcional as well as function pointer. But when I want
to use another class's member function, how could I do?
See example:
class TestPrint
{
public:
* * * * TestPrint( int i ) { start_num = i; }
* * * * void print( int i )
* * * * {
* * * * * * * * cout << endl<< "| * * * *" <<i + start_num <<
" * * * * * * * *|" << endl;
* * * * }
private:
* * * * int start_num;
};
int main()
{
* * * * TestPrint* pTest = new TestPrint( 8 );
* * * * int *a[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
* * * * for_each( a, a + 9, /*** Use the pTest's "print" ***/);
* * * * delete pTest;
* * * * return 0;
}
/*** Use the pTest's "print" ***/ is where I want to write code .
sorry
* * * * for_each( a, a + 9, /*** Use the pTest's "print" ***/);
should be
* * * * for_each( a, a + 10, /*** Use the pTest's "print" ***/ );

You can use binders like boost::bind, or standard binders like bind1st
(here) / bind2nd along with std::mem_fun_ref.

* * * * * * * * for_each( a, a + 9, bind(&TestPrint::print, pTest, _1));

Make the *print member a const member function, else std:: binders
won't probably work.
please tell me how to use standard binders like bind1st
(here) / bind2nd along with std::mem_fun_ref.

Thank you!
Jul 12 '08 #4

P: n/a
On Jul 12, 4:54*am, "want.to.be.professer" <guolihui...@gmail.com>
wrote:
We know that alomost every algorithm function, such as for_each,
find_if, *use funcional as well as function pointer. But when I want
to use another class's member function, how could I do?

See example:

class TestPrint
{
public:
* * * * TestPrint( int i ) { start_num = i; }
* * * * void print( int i )
* * * * {
* * * * * * * * cout << endl<< "| * * * *" << i +start_num <<
" * * * * * * * *|" << endl;
* * * * }
private:
* * * * int start_num;

};

int main()
{
* * * * TestPrint* pTest = new TestPrint( 8 );
* * * * int *a[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
* * * * for_each( a, a + 9, /*** Use the pTest's "print" ***/ );
* * * * delete pTest;
* * * * return 0;

}

/*** Use the pTest's "print" ***/ is where I want to write code .
First the obvious:

struct foo
{
TestPrint* testPrint;
foo( TestPrint* tp ): testPrint( tp ) { }
void operator()( int i ) {
testPrint->print( i );
}
};

for_each( a, a + 9, foo( pTest ) );

the above structure can be built with the standard functional objects
as well:
for_each( a, a + 9, bind1st( mem_fun( &TestPrint::print ), pTest ) );

mem_fun wraps TestPrint::print into a function object that takes two
parameters (TestPrint* and int), and bind1st wraps the mem_fun into a
function object that always passes pTest as the first parameter.
Jul 12 '08 #5

P: n/a
On Jul 12, 10:24*pm, "Daniel T." <danie...@earthlink.netwrote:
On Jul 12, 4:54*am, "want.to.be.professer" <guolihui...@gmail.com>
wrote:
We know that alomost every algorithm function, such as for_each,
find_if, *use funcional as well as function pointer. But when I want
to use another class's member function, how could I do?
See example:
class TestPrint
{
public:
* * * * TestPrint( int i ) { start_num = i; }
* * * * void print( int i )
* * * * {
* * * * * * * * cout << endl<< "| * * * *" << i+ start_num <<
" * * * * * * * *|" << endl;
* * * * }
private:
* * * * int start_num;
};
int main()
{
* * * * TestPrint* pTest = new TestPrint( 8 );
* * * * int *a[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
* * * * for_each( a, a + 9, /*** Use the pTest's "print" ***/ );
* * * * delete pTest;
* * * * return 0;
}
/*** Use the pTest's "print" ***/ is where I want to write code .

First the obvious:

struct foo
{
* * * * TestPrint* testPrint;
* * * * foo( TestPrint* tp ): testPrint( tp ) { }
* * * * void operator()( int i ) {
* * * * * * * * testPrint->print( i );
* * * * }

};

for_each( a, a + 9, foo( pTest ) );

the above structure can be built with the standard functional objects
as well:

for_each( a, a + 9, bind1st( mem_fun( &TestPrint::print ), pTest ) );

mem_fun wraps TestPrint::print into a function object that takes two
parameters (TestPrint* and int), and bind1st wraps the mem_fun into a
function object that always passes pTest as the first parameter.
en, Thank you
for_each( a, a + 9, bind1st( mem_fun( &TestPrint::print ), pTest ) );
this is what I want,
I'd better review the STL.
Jul 12 '08 #6

P: n/a
In article <e66af743-5009-4e68-bfe6-5734bd324ab4
@k13g2000hse.googlegroups.com>, gu*********@gmail.com says...

[ ... ]
class TestPrint
{
public:
TestPrint( int i ) { start_num = i; }
void print( int i )
{
cout << endl<< "| " << i + start_num <<
" |" << endl;
}
private:
int start_num;
};

int main()
{
TestPrint* pTest = new TestPrint( 8 );
Why are you allocating this dynamically? You're doing dynamic
allocation, but using it to imitate automatic allocation (i.e.
allocating it as you enter a scope and deleting it as you leave that
scope). With that given, automatic allocation would be far more suitable
under the circumstances.
int a[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
for_each( a, a + 9, /*** Use the pTest's "print" ***/ );
The direct, obvious answers to your question would involve things like
mem_fun or mem_fun_ref. Personally, however, I've become convinced that
while these were well intended, using them is a mistake far more often
than not. Code using them is rarely readable, and (more importantly)
over time I've become convinced that they're _usually_ a sign of poor
design anyway.

It's less obvious, but when you get down to it, TestPrint is really a
functor. All you ever do with it is create it, and then invoke one
member function -- and that member function is basically a repetition of
the verb in the name of the class. The 'print' doesn't add any useful
information -- TestPrint() would mean as much as TestPrint::print().

General observation: when a class name is primarily a verb instead of a
noun, there's a pretty good chance that class should be a functor.

What I think you really should do is change your code to more accurately
reflect the nature of TestPrint, making it a real functor.

class TestPrint {
int start_num;
public:
TestPrint(int i) : start_num(i) {}
void operator()(int i) {
cout << endl<< "| "
<< i + start_num
<< " |" << endl;
}
};

Having done that, invocation becomes trivial:

int main() {
int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
for_each(a, a+9, TestPrint(8));
return 0;
}

Contrary to what you said elsthread, in this case it should be a+9, NOT
a+10. IMO, it's worthwhile to write code to handle this for you though:

template <class T, size_t N>
T *end(T (&a)[N]) {
return a+N;
}

Then you can use:

for_each(a, end(a), TestPrint(8));

Though it's not really related to your original question, there's also
the minor detail of the formatting you used for the output. At a guess,
this is probably closer to what you really wanted:

cout << "|" << setw(10) << i+start_num << setw(17) << "|" << endl;

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jul 12 '08 #7

P: n/a
On Jul 12, 11:58*am, Jerry Coffin <jcof...@taeus.comwrote:
<snip>
Contrary to what you said elsthread, in this case it should be a+9, NOT
a+10. IMO, it's worthwhile to write code to handle this for you though:

template <class T, size_t N>
T *end(T (&a)[N]) {
* * * * return a+N;
All great points here; I very much agree. Except "a+10" _is_ correct.

Although we won't hold you responsible, since your helper function
would return the correct amount in this case.

Joe Cook
Jul 12 '08 #8

P: n/a
On Jul 12, 11:58*pm, Jerry Coffin <jcof...@taeus.comwrote:
In article <e66af743-5009-4e68-bfe6-5734bd324ab4
@k13g2000hse.googlegroups.com>, guolihui...@gmail.com says...
Thanks for your explaination.But I cann't get the follow advise :
Contrary to what you said elsthread, in this case it should be a+9, NOT
a+10. IMO,
Let's look at the source code of " for_each ":

// for_each. Apply a function to every element of a range.
template <class _InputIter, class _Function>
_Function for_each(_InputIter __first, _InputIter __last,
_Function __f) {
__STL_REQUIRES(_InputIter, _InputIterator);
for ( ; __first != __last; ++__first)
__f(*__first);
return __f;
}

Note the "__first != __last" .When used a+9, at the end, __first ==
&a[9], but a[9] is never printed.
So I thind "a+10" is correct.
Jul 13 '08 #9

P: n/a
In article <d5fd36ec-ce61-49d4-b1f1-
05**********@d1g2000hsg.googlegroups.com>, gu*********@gmail.com says...
On Jul 12, 11:58*pm, Jerry Coffin <jcof...@taeus.comwrote:
In article <e66af743-5009-4e68-bfe6-5734bd324ab4
@k13g2000hse.googlegroups.com>, guolihui...@gmail.com says...
Thanks for your explaination.But I cann't get the follow advise :
Contrary to what you said elsthread, in this case it should be a+9, NOT
a+10. IMO,
As well you shouldn't -- I just plain screwed up.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jul 13 '08 #10

This discussion thread is closed

Replies have been disabled for this discussion.