纯净、安全、绿色的下载网站

首页|软件分类|下载排行|最新软件|IT学院

当前位置:首页IT学院IT技术

c++11闭包的实现 浅谈c++11闭包的实现

lsgxeva   2021-06-09 我要评论
想了解浅谈c++11闭包的实现的相关内容吗lsgxeva在本文为您仔细讲解c++11闭包的实现的相关知识和一些Code实例欢迎阅读和指正我们先划重点:c++,闭包下面大家一起来学习吧

什么是闭包

一个函数带上了一个状态就变成了闭包了那什么叫 “带上状态” 呢? 意思是这个闭包有属于自己的变量这些个变量的值是创建闭包的时候设置的并在调用闭包的时候可以访问这些变量

函数是代码状态是一组变量将代码和一组变量捆绑 (bind) 就形成了闭包

闭包的状态捆绑必须发生在运行时

仿函数:重载 operator()

#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <string>
#include <memory>
#include <vector>
#include <map>


class MyFunctor
{
public:
    MyFunctor(int temp): round(temp) {}
    int operator()(int temp) {return temp + round; }
private:
    int round;
};


void mytest()
{
    int round = 2;
    MyFunctor f(round);
    std::cout << "result: " << f(1) << std::endl; // operator()(int temp)

    return;
}

int main()
{
    mytest();

    system("pause");
    return 0;
}

std::bind绑定器

在C++中可调用实体主要包括:函数、函数指针、函数引用、可以隐式转换为函数指定的对象或者实现了opetator()的对象

C++11中新增加了一个std::function类模板它是对C++中现有的可调用实体的一种类型安全的包裹通过指定它的模板参数它可以用统一的方式处理函数、函数对象、函数指针并允许保存和延迟执行它们

std::function对象最大的用处就是在实现函数回调使用者需要注意它不能被用来检查相等或者不相等但是可以与NULL或者nullptr进行比较

#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <string>
#include <memory>
#include <functional>
#include <vector>
#include <map>

void func(void)
{// 普通全局函数
    std::cout << __FUNCTION__ << std::endl;
}

class Foo
{
public:
    static int foo_func(int a)
    {// 类中的静态函数
        std::cout << __FUNCTION__ << "(" << a << ")->: ";
        return a;
    }
};

class Bar
{
public:
    int operator ()(int a)
    {// 仿函数
        std::cout << __FUNCTION__ << "(" << a << ")->: ";
        return a;
    }
};

void mytest()
{
    // std::function对象最大的用处就是在实现函数回调使用者需要注意它不能被用来检查相等或者不相等但是可以与NULL或者nullptr进行比较

    // 绑定一个普通函数
    std::function< void(void) > f1 = func;
    f1();

    // 绑定类中的静态函数
    std::function<int(int)> f2 = Foo::foo_func;
    std::cout << f2(11) << std::endl;

    // 绑定一个仿函数
    Bar obj;
    std::function<int(int)> f3 = obj;
    std::cout << f3(222) << std::endl;

    /*
     运行结果:
     func
     Foo::foo_func(11)->: 11
     Bar::operator ()(222)->: 222
    */

    return;
}

int main()
{
    mytest();

    system("pause");
    return 0;
}

std::bind

std::bind是这样一种机制它可以预先把指定可调用实体的某些参数绑定到已有的变量产生一个新的可调用实体这种机制在回调函数的使用过程中也颇为有用

C++98中有两个函数bind1st和bind2nd它们分别可以用来绑定functor的第一个和第二个参数它们都是只可以绑定一个参数各种限制使得bind1st和bind2nd的可用性大大降低

在C++11中提供了std::bind它绑定的参数的个数不受限制绑定的具体哪些参数也不受限制由用户指定这个bind才是真正意义上的绑定

#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <string>
#include <memory>
#include <functional>
#include <vector>
#include <map>


void func(int x, int y)
{
    std::cout << x << " " << y << std::endl;
}


void mytest()
{
    std::bind(func, 1, 2)();
    std::bind(func, std::placeholders::_1, 2)(1);
    func(1, 2);

    // std::placeholders 表示的是占位符
    // std::placeholders::_1是一个占位符代表这个位置将在函数调用时被传入的第一个参数所替代
    std::bind(func, 2, std::placeholders::_1)(1);
    std::bind(func, 2, std::placeholders::_2)(1, 2);
    std::bind(func, std::placeholders::_1, std::placeholders::_2)(1, 2);
    std::bind(func, std::placeholders::_3, std::placeholders::_2)(1, 2, 3);
    
    //std::bind(func, 2, std::placeholders::_2)(1); // err, 调用时没有第二个参数

    return;
}

int main()
{
    mytest();

    system("pause");
    return 0;
}

std::bind和std::function配合使用

通过std::bind和std::function配合使用所有的可调用对象均有了统一的操作方法

#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <string>
#include <memory>
#include <functional>
#include <vector>
#include <map>


class Test
{
public:
    int i; // 非静态成员变量

    void func(int x, int y)
    { // 非静态成员函数
        std::cout << x << " " << y << std::endl;
    }
};

void mytest()
{
    Test obj; // 创建对象
    // 绑定非静态成员函数
    std::function<void(int, int)> f1 = std::bind(&Test::func, &obj, std::placeholders::_1, std::placeholders::_2);
    f1(1, 2); // 输出: 1 2

    obj.i = 10;
    // 绑定非静态成员变量
    std::function<int &()> f2 = std::bind(&Test::i, &obj);
    f2() = 123;  // obj.i = 123;
    std::cout << "obj.i: " << obj.i << std::endl;

    return;
}

int main()
{
    mytest();

    system("pause");
    return 0;
}

相关文章

猜您喜欢

  • docker容器与镜像的区别 聊聊docker中容器与镜像的区别

    想了解聊聊docker中容器与镜像的区别的相关内容吗天下没有收费的bug在本文为您仔细讲解docker容器与镜像的区别的相关知识和一些Code实例欢迎阅读和指正我们先划重点:docker容器与镜像的区别,docker容器,docker镜像下面大家一起来学习吧..
  • Python添加类型标注 浅谈怎么给Python添加类型标注

    想了解浅谈怎么给Python添加类型标注的相关内容吗枇杷鹭在本文为您仔细讲解Python添加类型标注的相关知识和一些Code实例欢迎阅读和指正我们先划重点:Python添加类型标注,Python类型标注下面大家一起来学习吧..

网友评论

Copyright 2020 www.fresh-weather.com 【世纪下载站】 版权所有 软件发布

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 点此查看联系方式