ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

std::bind绑定unique_ptr

2022-09-08 18:30:49  阅读:213  来源: 互联网

标签:std bind Leno func unique ptr 模板


问题的来源,绑定和unique_ptr

std::bind绑定unique_ptr的时候生成的类型并非std::function,而是一个不可拷贝的类型,这跟unique_ptr的特性有关,这意味着如果需要暂时保存绑定的函数,没有能够接受对象的类型声明

如果不需要保存可以使用auto来接受绑定的对象,然后调用


void Test(int val)
{
    
}

std::unique_ptr<int> up = std::make_unique<int>();
// 错误的,无法通过编译
// std::function<void()> func = std::bind(&Test, std::move(up)); 
// 正确的,可以通过编译
auto func = std::bind(&Test, std::move(up));

其实这是绑定生成了一个不可拷贝(只可移动)的闭包类型,而std::function是可以拷贝的因此类型不匹配(就算在bind外面套一个std::move也不会有作用)

	std::_Binder<std::_Unforced,void (__cdecl*)(int),std::unique_ptr<int,std::default_delete<int>>>

其实绑定后的函数是一个内部类型

用模板

template<typename F>
class Leno
{
public:
    Leno(F& func) : task_(std::move(func)) { }
    void Run() { task_(); }
private:
    F task_;
};

用模板可以保存这种类型的闭包对象,这样就可以在需要的时候再使用了,但是有一个问题,就是这种模板,会要求Leno对象在使用时提供模板参数,这又回到了一开始的问题,这个类型是内部类型,无法提供,那么Leno对象就无法构造。

外部无感知

那就需要对外无感知,在外部想要保存这么一个闭包对象时,完全不需要提供这个闭包对象的类型,需要利用继承和模板

class LenoBase
{
public:
    virtual void Run() { }
};


template<typename F>
class Leno : public LenoBase
{
public:
    Leno(F& func) : task_(std::move(func)) { }
    void Run() override { task_(); }
private:
    F task_;
};

class LenoCallback
{
public:
    LenoCallback(std::shared_ptr<LenoBase> bs) : b_(bs) {}
    void Run() { b_->Run(); }
private:    
    std::shared_ptr<LenoBase> b_;
};

template<typename F>
LenoCallback Get(F& func)
{
    return LenoCallback(std::make_shared<Leno<F>>(func));
}

template<typename F>
std::unique_ptr<LenoCallback> GetUnique(F& func)
{
    return std::make_unique<LenoCallback>(std::make_shared<Leno<F>>(func));
}

int main() {
    std::unique_ptr<int> test = std::make_unique<int>(100);
    //auto func([pw = std::move(test)]() {
    //    cout << *pw << endl;
    //    });

    auto func = std::bind(&hahahha, std::move(test));
    function<void()> func1 = std::bind(&lalala, 10);
    std::unique_ptr<LenoCallback> callback = GetUnique(func);
    callback->Run();

    return 0;
}
  1. 基础类型LenoBase是不需要模板参数的,因此,在对外开放的类型LenoCallback中有该类型的指针,这时,LenoCallback就不需要模板参数;
  2. 需要模板参数的是Leno实现类,在函数中创建该类对象,只需要函数模板,并且利用多态实现父类指针调用子类方法;
  3. LenoBase基础类需要提供一定的虚函数实现接口;

到这里就完成了绑定unique_ptr闭包的保存,并且对外的GetGetUnique函数也不需要提供类型

标签:std,bind,Leno,func,unique,ptr,模板
来源: https://www.cnblogs.com/lenomirei/p/16670493.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有