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

  • Thread starter want.to.be.professer
  • Start date
W

want.to.be.professer

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 .
 
W

want.to.be.professer

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" ***/ );
 
A

Abhishek Padmanabh

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.
 
W

want.to.be.professer

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 .
        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!
 
D

Daniel T.

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.
 
W

want.to.be.professer

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.
 
J

Jerry Coffin

[ ... ]
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;
 
J

joseph cook

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
 
W

want.to.be.professer

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.
 

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,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top