IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> C++11中的std::function和std::bind -> 正文阅读

[游戏开发]C++11中的std::function和std::bind

1.std:bind

std:bind是一个函数模板,可以用来绑定一切函数

1.1 绑定普通成员函数,普通静态成员函数,普通模板函数

例子:

#include <functional>
#include <iostream>
#include <cstdio>

void fun(int a, int b)
{
    std::cout <<a+b<<std::endl;
}

int main()
{
    auto funBind = std::bind(fun, 4, 6);
    funBind();
    return 0;
}

结果为

10

上面的例子中函数fun被绑定到了funBind中,fun中的参数被绑定到了一个固定的值,当然你也可以不指定它的值,在绑定值时给它一个缺省值,即绑定到占位符(std::placeholders)上,如下:

#include <functional>
#include <iostream>
#include <cstdio>

void fun(int a, int b)
{
    std::cout << a + b << std::endl;
}

//绑定到静态函数
static void staticfun(int a, int b)
{
    std::cout << a + b << std::endl;
}

//绑定到模板函数
template<typename A, typename B>
inline void addFun(A a, B b)
{
    std::cout << a + b << std::endl;
}

int main()
{
    auto funBind = std::bind(fun, std::placeholders::_1, 6);
    funBind(4);


    auto funBind1 = std::bind(staticfun, std::placeholders::_1, std::placeholders::_2);
    funBind1(5, 6);

    auto funBind2 = std::bind(addFun<int,int>, std::placeholders::_1, std::placeholders::_2);
    funBind2(6, 6);

    return 0;
}

结果:

10
11
12

需要注意的是:绑定到模板函数的时候,第一个参数需要指定参数的类型

1.2 绑定类成员函数,类静态成员函数,类模板函数

需要注意的是:在绑定类成员函数时,bind的第一个参数为对象的成员函数指针,第二个参数为一个具体的对象实例指针,如下

#include <functional>
#include <iostream>
#include <cstdio>

class S {
public:
    void fun(int a, int b)
    {
        std::cout << a + b << std::endl;
    }

    //绑定到静态函数
    static void staticfun(int a, int b)
    {
        std::cout << a + b << std::endl;
    }

    template<typename A, typename B>
    inline void addFun(A a, B b)
    {
        std::cout << a + b << std::endl;
    }
    
};
int main()
{
    S s;

    auto funBind = std::bind(&S::fun,&s,std::placeholders::_1, 6);
    funBind(4);

    auto funBind1 = std::bind(&S::staticfun, std::placeholders::_1, std::placeholders::_2);
    funBind1(5,6);
 
    auto funBind2 = std::bind(&S::addFun<int,int>, &s,std::placeholders::_1, std::placeholders::_2);
    funBind2(6, 6);

    return 0;
}

结果:

10
11
12

需要注意的是成员函数的访问权限为public,在绑定静态成员函数时,第二个参数不需要指定具体对象实例的地址

1.3 绑定引用参数

先看例子:

#include <functional>
#include <iostream>
#include <cstdio>

int add(int& a, const int& b)
{ 
    return a+b; 
}

int main()
{
    int a = 2, b = 4;

    auto funcBind = std::bind(add, std::ref(a), std::cref(b));

    std::cout << funcBind() << std::endl;

    return 0;
}
```c
结果为:
```c
6

在上面的例子a为普通引用,在绑定传递值时调用ref即可,而b为常量引用,在绑定传递值时调用cref即可

1.4 绑定lambda表达式

#include <functional>
#include <iostream>
#include <cstdio>

auto lambda = [](int a, int b)
{
    return a + b;
};

int main()
{
    int a = 2, b = 4;

    auto funcBind = std::bind(lambda, a, b);

    std::cout << funcBind() << std::endl;

    return 0;
}

结果:

6

2.std::function

2.1 封装普通函数/静态函数/lambda表达式

std::function是一个函数模板类,是一个类,定义在头文件可以用其定义不同的对象,对象的类型可以是普通函数,静态函数以及Lambda表达式,在不用std::function之前,定义一个函数指针通常用以下方法定义,如:

typedef void (*funPtr)(int,int);

使用std::function之后,这样定义

std::function<void(int ,int)> funPtr;

通常这样子使用,先定义一个函数,再将这个函数指针赋值给一个std::function对象,如下

#include <functional>
#include <iostream>
#include <cstdio>

void fun(int a, int b)
{
    std::cout << a + b << std::endl;
}

static void fun1(int a, int b)
{
    std::cout << a + b << std::endl;
}

auto lambda = [](int a, int b)
{
    std::cout << a + b << std::endl;
};

int main()
{
    std::function<void(int, int)> funPtr = fun;
    funPtr(1, 2);

    std::function<void(int, int)> funPtr1 = fun1;
    funPtr1(2, 2);

    std::function<void(int, int)> funPtr2 = lambda;
    funPtr2(3, 2);

    return 0;
}

结果:
3
4
5

2.2 绑定成员函数/静态成员函数/函数模板/成员变量

在封装成员函数/静态成员函数时,std::functionstd::bind搭配使用

#include <functional>
#include <iostream>
#include <cstdio>

class S {
public:
    int num;
    void fun(int a, int b)
    {
        std::cout << a + b << std::endl;
    }

    //绑定到静态函数
    static void staticfun(int a, int b)
    {
        std::cout << a + b << std::endl;
    }

    template<typename A, typename B>
    inline void addFun(A a, B b)
    {
        std::cout << a + b << std::endl;
    }

};
int main()
{
    S s;

    //错误的,不可以使用 std::function指向类的非静态成员
    //std::function<void(int, int)> funBind = std::bind(&S::fun, &s, std::placeholders::_1, 6);
    //funBind(4);

    std::function<void(int, int)> funBind1 = std::bind(&S::staticfun, std::placeholders::_1, std::placeholders::_2);
    funBind1(5, 6);

    std::function<void(int, int)> funBind2 = std::bind(&S::addFun<int, int>, &s, std::placeholders::_1, std::placeholders::_2);
    funBind2(6, 6);

    //绑定成员变量
    std::function<int& ()> MyValue = std::bind(&S::num, &s);
    MyValue() = 1000;//相当于s.num=1000
    std::cout << "num = "<<s.num<< std::endl;

    return 0;
}

结果:

11
12
num = 1000

需要注意的是不可以使用 std::function指向类的非静态成员,可以用函数指针的形式表示或者在类中直接绑定,如下:

#include <iostream>
#include <vector>
#include <functional>

class Father
{
public:
    void Called() {
        for (int i = 0; i < Vec.size(); i++)
            Vec[i]();
    }
protected:
    std::vector<std::function<void()>> Vec;
};
class Son : public Father
{
public:
    Son()
    {
        std::function<void()> fun1 = std::bind(&Son::A, this);
        std::function<void()> fun2 = std::bind(&Son::B, this);
        Vec.push_back(fun1);
        Vec.push_back(fun2);
    }
private:
    void A() { std::cout << "A\n"; }
    void B() { std::cout << "B\n"; }
};

int main()
{
    Son d;
    d.Called();
    return 0;
}

结果:

A
B
  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-10-07 14:07:54  更:2021-10-07 14:08:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/28 2:36:33-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码