200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > 类的成员函数作为函数指针

类的成员函数作为函数指针

时间:2020-04-03 14:10:29

相关推荐

类的成员函数作为函数指针

网上找了半天没找到,还是看官方文档比较清晰:std::function - (polytechnique.fr)

同时给出自己设计C类型的成员函数指针的形式。

其实函数指针要给函数的地址,那么地址一定要是全局的才可以。所以实现有两种思路,一种是直接再类中定义一个静态成员函数;另一种是可以用全局函数回调std::function定义的可调用对象函数。std::function的好处是可以局部使用不用全局。

#include<iostream>#include<functional>typedef int(*AddPtr)(int, int);std::function<int(int, int)> add_callback;class Cal{public:static int s_add(int x, int y){std::cout << "static fun : \n";return x + y;}int add(int x, int y){return x + y;}};void fun(int a, int b, std::function<int(int, int)> ptr){std::cout << "use function :\n";int res = ptr(a, b);std::cout << "a + b = " << res << "\n";}void fun(int a, int b, AddPtr ptr){std::cout << "no use function :\n";int res = ptr(a, b);std::cout << "a + b = " << res << "\n";}// 全局函数形式int g_add(int x, int y){return add_callback(x, y);}int main(){Cal cal;add_callback = std::bind(&Cal::add, cal, std::placeholders::_1, std::placeholders::_2);fun(5, 7, add_callback);AddPtr ptr = g_add;fun(5, 7, ptr);AddPtr ptr2 = &Cal::s_add;fun(5, 7, ptr2);}

如果有多个类的成员函数都想使用函数指针的形式调用,每个成员函数都要写一个全局的函数非常的麻烦,所以可以使用模板让编译器来生成的代码,这样写一份等于无数份。具体示例如下:

#include <type_traits>#include <iostream>#include <utility>#include<iostream>#include<functional>typedef int(*AddPtr)(int, int);class Cal{public:int add(int x, int y){return x + y;}};void fun(int a, int b, AddPtr ptr){std::cout << "no use function :\n";int res = ptr(a, b);std::cout << "a + b = " << res << "\n";}template <typename Callable>union storage{storage() {}std::decay_t<Callable> callable;};template <int, typename Callable, typename Ret, typename... Args>auto fnptr_(Callable &&c, Ret (*)(Args...)){static bool used = false;static storage<Callable> s;using type = decltype(s.callable);if (used)s.callable.~type();new (&s.callable) type(std::forward<Callable>(c));used = true;return [](Args... args) -> Ret{return Ret(s.callable(std::forward<Args>(args)...));};}template <typename Fn, int N = 0, typename Callable>Fn *fnptr(Callable &&c){return fnptr_<N>(std::forward<Callable>(c), (Fn *)nullptr);}int main(){Cal cal;// Right :// auto fun_ptr = std::bind(&Cal::add, cal, std::placeholders::_1, std::placeholders::_2);// AddPtr lambda_add = fnptr<int(int,int)>([&fun_ptr](int x, int y){return fun_ptr(x, y);});// AddPtr lambda_add = fnptr<int(int,int)>(std::bind(&Cal::add, cal, std::placeholders::_1, std::placeholders::_2));// AddPtr lambda_add = fnptr<int(int,int)>(fun_ptr);// fun(5, 6, lambda_add);// Error :std::function<int(int, int)> fun_ptr = std::bind(&Cal::add, cal, std::placeholders::_1, std::placeholders::_2);AddPtr lambda_add = fnptr<int(int,int)>(fun_ptr);fun(5, 6, lambda_add);}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。