2014-11-01 2 views
0

Скажем, у меня есть функция foo:Как передать функцию-член в качестве параметра функции, которая этого не ожидает?

void foo(void (*ftn)(int x)) 
{ 
    ftn(5); 
} 

Она нуждается в качестве параметра void функцию, которая принимает Int в качестве параметра. Рассмотрим

void func1(int x) {} 

class X { 
public: 
    void func2(int x) {} 
}; 

Теперь foo(&func1) нормально.

Но foo(&X::func2) не нормально, потому что X::func2 не статична и нуждается в объекте контекста и его указатель функции типа отличается.

Я пробовал foo(std::bind(&X:func2, this)) изнутри X, но это также вызывает несоответствие типа.

Каков правильный способ сделать это?

+0

Рассмотрите возможность изменения функции, чтобы принять 'std :: function' в качестве аргумента. Таким образом, вы можете использовать 'std :: bind' для прозрачного использования либо свободной функции, либо статической функции-члена, либо нестатической функции-члена. –

+0

Функция шаблона foo, скорее всего, самое простое решение. Изменить: Да, как упоминалось выше, еще проще может быть std :: function – Creris

+0

Что делать, если мне не разрешено изменять 'foo' (часть библиотеки)? – batman

ответ

2

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

struct XFunc2Wrapper { 
    static X* x; 

    static void func2(int v) { 
     x->func2(v); 
    } 
}; 

А потом просто сделать foo(&XFunc2Wrapper::func2) после того, как вы установили XFunc2Wrapper::x, чтобы быть вашим X. Он не должен быть вложен в структуру, это может быть просто какой-то глобальный указатель, но вложенность помогает лучше понять цель кода.

Но это, безусловно, должно быть в крайнем случае после того, как (согласно Капитану Обилийству) пытается сделать foo(std::function<void(int)>).

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