2013-08-22 7 views
0

Я следующий вызов:Передача функции в качестве аргумента в C++

void Derived::GetEntry(Skill&); 
InorderTraverse(GetEntry); 

Который называет

void Base<ItemType>::InorderTraverse(void Visit(ItemType&)) const 

Попытка собрать как написано генерирует

ошибка C3867: «Derived :: GetEntry ': список вызовов отсутствующих аргументов функции; использовать '& Производного :: GetEntry', чтобы создать указатель на член

Использование & Derived :: GetEntry генерирует

не может преобразовать параметр 1 из «недействительных (__thiscall Derived :: *) (Skill &)»в„пустоты (__cdecl *) (ItemType &)“

изменяющегося заявление в статическую ничтожную GetEntry ... устраняет эти проблемы, но и создает новый набор проблем (а именно, что я не могу переменный ток (нестатические ссылки на элементы должны относиться к определенному объекту)

У меня есть аналогичная операция обхода, которая отлично работает со статическим объявлением, поскольку вызываемая функция просто отображает информацию о каждом объекте, на который она вызывается ,

Я искал несколько дней для ответа, и мне кажется, что это что-то простое. Есть ли способ использовать нестатические функции в качестве параметра в другом вызове функции?

Полный код: https://github.com/mindaika/SkillTree

+0

Дубликат http://stackoverflow.com/questions/400257/how-can-i-pass-a-class-member-function-as-a -callback –

+1

Не видеть фактический код делает его несколько проблематичным в понимании этого вопроса (по крайней мере для меня). Первый фрагмент не является даже допустимым кодом C++, так как первая строка является * объявлением *, а вторая является действительным вызовом функции. Что такое * актуальная * проблема? Вы пытаетесь передать функцию «указатель-член» другой функции, которая будет использоваться для алгоритма перечисления? Связанный с Zac вопрос охватывает это красиво. – WhozCraig

+0

, если вы точно знаете, какие функции вы передадите, и эти функции доступны из контекста, в котором вы хотите их вызвать, вы можете заменить эту функцию, проходящую перечислимым, и сделать переключатель на сайте вызова. Конечно, это не так гибко. – didierc

ответ

0

Как я упоминал в своем вопросе, я пытался обойти «утечку памяти», вызванную использованием статической переменной (на самом деле это не утечка, поскольку статика уничтожена, но только после утечки детектор работает). Я закончил использовать модификацию инкапсулированного указателя, описанную здесь: C++ freeing static variables

3

Edit: Поставлен полный рабочий пример вместо этого.

Я предлагаю вам вместо этого использовать указатели на функции std.

Например:

#include <functional> 
void main() 
{ 
class TheClass 
{ 
public: 

    TheClass() 
    { 
     m_function = (std::tr1::bind(&TheClass::run, this)); 
    }; 

    void run() 
    { 
      // stuff to do 
    }; 

    std::tr1::function<void()> m_function; 
}; 

TheClass theclass; 
theclass.m_function(); 

} 

m_function(); // функция вызова

+0

Или просто используйте C++ 11 вместо добавления ':: tr1' everytime или boost, если C++ 03 является обязательным. +1 в любом случае. –

+0

@Adam Я попробовал представленный вами пример, измененный для моего кода, но он не работает. Однако, прочитав некоторые из других комментариев, это выглядит так: :: bind в конечном итоге является решением, и мне просто нужно понять, как правильно его использовать. Спасибо! –

Смежные вопросы