zoukankan      html  css  js  c++  java
  • C++闭包到C函数指针转化

    #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!");

  • 相关阅读:
    vscode英文显示设置为中文语言
    vscode各插件使用-背景图-scss
    公众号关联小程序
    js点击遮罩空白区域关闭,点击遮罩内元素不关闭
    swiper使用-点击跳转指定页
    小程序内部引导关注公众号实现方法
    jq赋值input值为空
    sass中代码使用
    Sources”参数中指定了多次。“Sources”参数不支持重复项
    将已存在小程序项目添加云开发配置
  • 原文地址:https://www.cnblogs.com/towik/p/4285544.html
Copyright © 2011-2022 走看看