for_each usage in C++

1k Views Asked by At
#include <list>
#include <algorithm>

class Abstract
{
    //contains a pure virtual function
};

class Mock
{
public:
   Mock();

 ~Mock()
 {
    std::for_each(m_abs_list.begin(), m_abs_list.end(), my_func);    
 } 

 void my_func(Abstract *ele){delete ele;} 

private:
   std::list <Abstract *> m_abs_list;
};

Basically, I am trying to call the destructor for each Abstract object in the m_abs_list. This can be easily achieved by a for loop. But I am trying to used for_each in this context.

On compilation I get error:

/usr/include/c++/4.2/bits/stl_algo.h: In function '_Function std::for_each(_InputIterator, _InputIterator, _Function) [with _InputIterator = std::_List_iterator<Abstract *>, _Function = void (Mock::*)(Abstract *)]'

/usr/include/c++/4.2/bits/stl_algo.h:159: error: must use '.*' or '->*' to call pointer-to-member function in '__f (...)'.

How do i get around the compilation error ?

5

There are 5 best solutions below

0
On

As others have pointed out, this is not the "right" way to do this. But, here is what you are trying to do...

std::for_each(m_abs_list.begin(), m_abs_list.end(),
              std::bind1st(std::mem_fun<void, Mock, Abstract*>(&Mock::my_func), this);

I am away from my development system, so there may be some syntax errors.

6
On

Don't go around it, fix it! ;) You've written . instead of , in here:

for_each(m_abs_list.begin(). m_abs_list.end(), my_func)

Also, no semicolon (;).

1
On

Some silly typos, but more importantly, you're trying to pass a member function as if it was a free function. Member functions require special usage- in the general case, you can use boost:bind. But in this case, since it doesn't depend on any instance variables, the easiest thing to do is just make it static.

Oh, and by the way, use smart pointers. Seriously. Do not use raw pointers.

0
On

You cannot use my_func like this because it is a member function and every member function is linked to a class and needs a pointer to this class to be used. In standard C++ you'd have to use bind functions (like bind1st) to create a functor that contains a pointer to your object that you can pass to the member function.

Of course, you can also directly makes a functor or use a free function ( or a static function in a class ). If you're using boost, you can also use boost::bind functions which are easier (it is not their only advantage) to write than standard ones. (and I don't mention boost or C++11 lambdas ).

If you don't know what a functor is, it is a class that redefines its operator() function. All STL algorithm are made to use them.

In your case, the easy way is just to create a free function. Of course, you should also use if you can smart pointers like boost::shared_ptr, you will gain considerable advantages in memory management.

2
On

You should use a smart pointer (other than auto_ptr) for memory management.

That way, when your member list is destroyed, it will release any heap-allocated memory along with it.

However, if you don't want to do that and unless you are restricted to using a compiler that doesn't support lambdas...

#include <list>
#include <algorithm>

class Abstract
{
    //contains a pure virtual function
};

class Mock
{
public:
   Mock();

 ~Mock()
 {
    std::for_each(m_abs_list.begin(), m_abs_list.end(), [](Abstract *ele)
    { delete ele; });
 } 

private:
   std::list <Abstract *> m_abs_list;
};