gpt4 book ai didi

C++模板回调去抖动函数

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:51:13 28 4
gpt4 key购买 nike

我一直在尝试想出一个模板化函数,在处理使用函数指针回调的 C API 时泛化反弹过程。

我基本上已经弄明白了,并且有一个可以工作的系统,但我想知道是否有办法清理最后一步。

假设您有一个采用函数指针和用户数据指针的 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) 的东西会返回一个指向实际反弹函数的指针。

这是一个有趣的练习,但我不太明白最后一 block 。

最佳答案

成员函数指针的类型包含类类型和函数签名。因此,您可以让模板函数参数推导为您处理:

template<class T, class Method, class ...Args>
static auto bounce(Method T::*func, T* priv, Args... args) -> decltype((priv->*m)(args...))
{
return (priv->*m)(args...);
}

使用 std::bind 可能更方便或 lambda 以完全隐藏它是成员函数调用的事实:

template<class Func, class ...Args>
static auto bounceCallable(Func func, Args... args) -> decltype(func(args...))
{
return func(args...);
}

你会这样调用它:

call_callback([&bar](int v){bar.baz(v);}, 11);

使用 lambda,您的语法比 std::bind 更好,但它的代价是必须重复签名。

关于C++模板回调去抖动函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28518364/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com