• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

C++闭包到C函数指针转化

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

#include <iostream>
#include <memory>
#include <functional>
#include <cassert>

// Raw Bind - simulating auto storage behavior for static storage data
template <typename BindFunctor, typename FuncWrapper> class scoped_raw_bind
{
public:

typedef scoped_raw_bind<BindFunctor, FuncWrapper> this_type;

// Make it Move-Constructible only
scoped_raw_bind(const this_type&) = delete;
this_type& operator=(const this_type&) = delete;
this_type& operator=(this_type&& rhs) = delete;

scoped_raw_bind(this_type&& rhs) : m_owning(rhs.m_owning)
{
rhs.m_owning = false;
}

scoped_raw_bind(BindFunctor b) : m_owning(false)
{
// Precondition - check that we don't override static data for another raw bind instance
if (get_bind_ptr() != nullptr)
{
assert(false);
return;
}
// Smart pointer is required because bind expression is copy-constructible but not copy-assignable
get_bind_ptr().reset(new BindFunctor(b));
m_owning = true;
}

~scoped_raw_bind()
{
if (m_owning)
{
assert(get_bind_ptr() != nullptr);
get_bind_ptr().reset();
}
}

decltype(&FuncWrapper::call) get_raw_ptr()
{
return &FuncWrapper::call;
}

static BindFunctor& get_bind()
{
return *get_bind_ptr();
}

private:

bool m_owning;

static std::unique_ptr<BindFunctor>& get_bind_ptr()
{
static std::unique_ptr<BindFunctor> s_funcPtr;
return s_funcPtr;
}

};

// Handy macro for creating raw bind object
// W is target function wrapper, B is source bind expression
#define RAW_BIND(W,B) std::move(scoped_raw_bind<decltype(B), W<decltype(B), __COUNTER__>>(B));

// Usage
///////////////////////////////////////////////////////////////////////////

// Target raw function signature
typedef void(*TargetFuncPtr)(double, int, const char*);

// Function that need to be called via bind
void f(double d, int i, const char* s1, const char* s2)
{
std::cout << "f(" << d << ", " << i << ", " << s1 << ", " << s2 << ")" << std::endl;
}

// Wrapper for bound function
// id is required to generate unique type with static data for
// each raw bind instantiation.
// THE ONLY THING THAT YOU NEED TO WRITE MANUALLY!
template <typename BindFunc, int id = 0> struct fWrapper
{
static void call(double d, int i, const char* s)
{
scoped_raw_bind<BindFunc, fWrapper<BindFunc, id>>::get_bind()(d, i, s);
}
};

 

一下为测试代码:

using namespace std::placeholders;

auto rf1 = RAW_BIND(fWrapper, std::bind(&f, _1, _2, _3, "This is f trail - 1"));
TargetFuncPtr f1 = rf1.get_raw_ptr();
f1(1.2345, 42, "f1: Bind! Bind!");


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
c#中间隔两个小时执行一次发布时间:2022-07-14
下一篇:
C/C++中printf和C++中cout的输出格式发布时间:2022-07-14
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap