首页 > C++ std::function<void(int)> 和 std::function<void()> 作为函数参数的注意事项

C++ std::function<void(int)> 和 std::function<void()> 作为函数参数的注意事项

前言

std::function 作为标准库提供的函数指针,使用起来还是比较方便的,不过在使用过程中有一些需要注意的细节,这里做一个简单的记录。

基本使用

  • 头文件: #include
  • 语法:std::function
    #include 
    #include 
    using namespace std;
    void func(int i, int g) { int count = 10;while (count > 0) { cout << "func: " << i  << " " << g<< endl;sleep(1);}
    }int main() { std::function<void(int,int)> job = func;job(10,10);return 0;
    }
    
    其中return_type 是函数指针的返回值类型,像上面案例中func函数的void类型。

    其中args_type 是函数指针的参数类型,有多个函数参数,就可以有多个数据类型。

函数指针作为参数 需要注意的事项

  1. 如果直接使用一个已经存在的函数来进行传参数,则需要声明调用者函数参数的std::function 为const类型。

    具体也就是类似 我们使用"dfafasd" 初始化一个 void test_string(std::string& res) 引用类型的字符串参数。这个时候因为是引用传递,而传递的时候却没有用变量,而是使用了一个常量,则需要保证这个函数的声明参数中有一个const ,才能将常量数据的地址正确得放在常量区域。即 正确的声明应该如 void test_string(const std::string& res)

    同理,std::function在使用一个已经存在的函数初始化的时候类似。如下代码是正确的:

    void  stl_func(const std::function<void(int, int)>& job, int num, int g) { job(num, g);
    }
    void func(int i, int g) { int count = 10;while (count > 0) { cout << "func: " << i  << " " << g<< endl;sleep(1);}
    }int main() { stl_func(func,10,1);return 0;
    }
    

    如果这个时候去掉了 stl_func 函数参数中的 const 声明,则会报如下错误:

    candidate function not viable: no know conversion from 'void()' to 'std::function &' 
    for 1'st argument.
    
  2. 使用一个函数指针变量 来进行参数传递,则不需要调用者函数参数的 std::function 为const。

    还是如上代码,修改之后:

    void  stl_func(std::function<void(int, int)>& job, int num, int g) { job(num, g);
    }
    void func(int i, int g) { int count = 10;while (count > 0) { cout << "func: " << i  << " " << g<< endl;sleep(1);}
    }int main() { std::function<void(int, int)> job = func;// 使用函数指针 变量进行传递就没有问题stl_func(job, 10, 10);return 0;
    }
    
  3. 在类的成员函数之间 将 std::function 作为参数传递时需要注意 如下使用过程:

    #include 
    #include using namespace std;
    void stl_func_bak(std::function<void()>& job) { job();
    }class Cb { public:static void cb_func() { while(1) { cout << "cb_func: " << 10 << endl;usleep(100000);}}void stl_cb_func() { // 函数成员作为传递的参数需要确保编译期间就能够分配好函数内存// 函数栈需要在编译期间获得内存,所以需要声明 cb_func 成员函数 为 staticstl_func_bak(Cb::cb_func);}
    };int main() { Cb* cb = new Cb();cb->stl_cb_func();return 0;
    }
    

欢迎大家补充使用过程中遇到的问题

更多相关:

  •         Apache POI是一个开源的利用Java读写Excel,WORD等微软OLE2组件文档的项目。        我的需求是对Excel的数据进行导入或将数据以Excel的形式导出。先上简单的测试代码:package com.xing.studyTest.poi;import java.io.FileInputSt...

  • 要取得[a,b)的随机整数,使用(rand() % (b-a))+ a; 要取得[a,b]的随机整数,使用(rand() % (b-a+1))+ a; 要取得(a,b]的随机整数,使用(rand() % (b-a))+ a + 1; 通用公式:a + rand() % n;其中的a是起始值,n是整数的范围。 要取得a到b之间的...

  • 利用本征图像分解(Intrinsic Image Decomposition)算法,将图像分解为shading(illumination) image 和 reflectance(albedo) image,计算图像的reflectance image。 Reflectance Image 是指在变化的光照条件下能够维持不变的图像部分...

  • 题目:面试题39. 数组中出现次数超过一半的数字 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。 你可以假设数组是非空的,并且给定的数组总是存在多数元素。 示例 1: 输入: [1, 2, 3, 2, 2, 2, 5, 4, 2] 输出: 2 限制: 1 <= 数组长度 <= 50000 解题: cl...

  • 题目:二叉搜索树的后序遍历序列 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。 参考以下这颗二叉搜索树:      5     /    2   6   /  1   3示例 1: 输入: [1,6,3,2,5] 输出...

  • 师弟总结的已经很好了 或者: 原工程需要导出的函数: extern "C" __declspec(dllexport) void Func(); 现工程导入这个函数: extern "C" __declspec(dllimport) void Func();...

  • 有使用过JS的朋友,相信都知道function。JS中的function是可以在里面在定义一个作为内部使用的。有时为了控制作用域,或者这种小函数只在这个函数体内会使用,所以就不希望在外部在作额外的定义。那C#中有没有这样类似的方式呢?答案是有的。 在C#中要实现,需要用到的是委托和lambda表达式。对于lambda表达式,是可以实...

  • 草色新雨中, 松声晚窗里。之前我们学习 Power Query 都是用鼠标就完成了很多复杂的操作。虽然 PowerQuery 已经将大部分常用功能内置成到功能区。基本能完成我们大部分的报表自动化功能。但是总有些复杂的或者个性化的问题是开发团队没有预先想到的,这时我们就需要学习 M 语言。一、M 语言在哪里?M语言的函数公式有三个地...

  • 前言从2020年3月份开始,计划写一系列文档--《小白从零开始学编程》,记录自己从0开始学习的一些东西。第一个系列:python,计划从安装、环境搭建、基本语法、到利用Django和Flask两个当前最热的web框架完成一个小的项目第二个系列:可能会选择Go语言,也可能会选择Vue.js。具体情况待定,拭目以待吧。。。基本概念表达式表...

  • 1.1函数1.1.1什么是函数函数就是程序实现模块化的基本单元,一般实现某一功能的集合。函数名:就相当于是程序代码集合的名称参数:就是函数运算时需要参与运算的值被称作为参数函数体:程序的某个功能,进行一系列的逻辑运算return 返回值:函数的返回值能表示函数的运行结果或运行状态。1.1.2函数的作用函数是组织好的,可重复使用的,用来...

  • 原标题:基于Python建立深度神经网络!你学会了嘛?图1 神经网络构造的例子(符号说明:上标[l]表示与第l层;上标(i)表示第i个例子;下标i表示矢量第i项)单层神经网络图2 单层神经网络示例神经元模型是先计算一个线性函数(z=Wx+b),接着再计算一个激活函数。一般来说,神经元模型的输出值是a=g(Wx+b),其中g是激活函数(...

  • 在学习MySQL的时候你会发现,它有非常多的函数,在学习的时候没有侧重。小编刚开始学习的时候也会有这个感觉。不过,经过一段时间的学习之后,小编发现尽管函数有很多,但是常用的却只有那几个。今天小编就把常用的函数汇总一下,为大家能够能好的学习MySQL中的函数。MySQL常使用的函数大概有四类。时间函数、数学函数、字符函数、控制函数。让我...