использование for_each в C ++ - PullRequest
0 голосов
/ 18 октября 2011
#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;
};

Обычно я пытаюсь вызвать деструктор для каждого Abstract объекта в m_abs_list. Это может быть легко достигнуто петлей for. Но я пытаюсь использовать for_each в этом контексте.

При компиляции я получаю ошибку:

/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 (...)'.

Как мне обойти ошибку компиляции?

Ответы [ 5 ]

4 голосов
/ 18 октября 2011

Некоторые глупые опечатки, но, что более важно, вы пытаетесь передать функцию-член, как если бы это была свободная функция.Функции-члены требуют специального использования - в общем случае вы можете использовать boost: bind.Но в этом случае, поскольку он не зависит от переменных экземпляра, проще всего сделать его статичным.

О, и, кстати, использовать умные указатели .Шутки в сторону.Не используйте сырые указатели.

4 голосов
/ 18 октября 2011

Не ходите вокруг, исправьте это! ;) Вы написали . вместо , здесь:

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

Кроме того, без точки с запятой (;).

1 голос
/ 19 октября 2011

Как уже отмечали другие, это не «правильный» способ сделать это. Но вот что вы пытаетесь сделать ...

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

Я удален от своей системы разработки, поэтому возможны некоторые синтаксические ошибки.

1 голос
/ 18 октября 2011

Вы должны использовать умный указатель (кроме auto_ptr) для управления памятью.

Таким образом, когда ваш список участников будет уничтожен, он освободит всю выделенную кучу память вместе с ним.

Однако, если вы не хотите этого делать, и если вы не ограничены использованием компилятора, который не поддерживает лямбда-выражения ...

#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;
};
1 голос
/ 18 октября 2011

Вы не можете использовать my_func таким образом, потому что это функция-член, и каждая функция-член связана с классом и нуждается в указателе на этот класс для использования. В стандартном C ++ вам придется использовать функции связывания (например, bind1st) для создания функтора, который содержит указатель на ваш объект, который вы можете передать функции-члену.

Конечно, вы также можете напрямую создать функтор или использовать свободную функцию (или статическую функцию в классе). Если вы используете boost, вы также можете использовать функции boost :: bind, которые проще (это не единственное их преимущество) писать, чем стандартные. (и я не упоминаю boost или C ++ 11 lambdas).

Если вы не знаете, что такое функтор, это класс, который переопределяет свою функцию operator (). Все алгоритмы STL созданы для их использования.

В вашем случае самый простой способ - просто создать бесплатную функцию. Конечно, вы должны также использовать умные указатели, такие как boost :: shared_ptr, вы получите значительные преимущества в управлении памятью.

...