Я пытаюсь придумать шаблонную функцию, которая обобщает процедуру отказов при работе с C API, использующими обратные вызовы функций.C++ templated callback bounce function
Я в основном выяснил это и имею рабочую систему, но мне интересно, есть ли способ очистить последний шаг.
Представьте, что у вас есть API, который принимает указатель на функцию и указатель данных пользователя. Вы хотите использовать метод экземпляра в качестве цели обратного вызова. Для этого требуется функция «отскока», которая переинтерпретирует указатель пользовательских данных как указатель экземпляра и вызывает метод с остальными аргументами.
В следующем примере кода работы:
#include <cstdio>
class Foo {
public:
Foo(int val) : val_(val) { }
void baz(int v) const
{
printf("baz %d\n", v + val_);
}
private:
int val_;
};
// Templated bounce function
template<class T, class Method, Method m, class Ret, class ...Args>
static Ret bounce(void *priv, Args... args)
{
return ((*reinterpret_cast<T *>(priv)).*m)(args...);
}
#define BOUNCE(c, m) bounce<c, decltype(&c::m), &c::m>
// Callback simulator
void call_callback(void (*func)(void *, int), void *priv, int v)
{
if (func) {
func(priv, v);
}
}
// Main Entry
int main()
{
Foo bar(13);
call_callback(&bounce<Foo, decltype(&Foo::baz), &Foo::baz>, &bar, 10);
call_callback(&BOUNCE(Foo, baz), &bar, 11);
return 0;
}
В основном я ищу способ, чтобы очистить использование. Макрос работает, но я пытаюсь вместо этого найти какую-то вспомогательную функцию, которая может просто принять параметр указателя метода, например &Foo::baz
, и вывести все параметры. Что-то вроде bounce_gen(&Foo::baz)
, которое вернет указатель на фактическую функцию отскока.
Это было веселое упражнение, но я не могу получить последний кусок.
Проблема в том, что отскок должен принимать только указатель и аргументы пользовательских данных 'void *'. Он не может принимать указатель на функцию-член. (Я не контролирую API обратного вызова). В вашем случае я понимаю, как работает дедукция параметров. Вместо этого мне нужно что-то сделать для вывода параметров и сгенерировать указатель функции bounce для перехода в API. –
А я вижу. Тот же принцип применяется. Сравнивая ваш макрос 'BOUNCE' и определение' bounce' в моем ответе, это сопоставление 'c == T',' decltype (& c :: m) == Метод T :: * 'и' & c :: m = = func'. – Pradhan