C++学习笔记(三十五):c++ 函数指针及lambda表达式

发布时间:2024年01月11日

本节介绍c++函数指针。在一些源码中经常能看到c++函数指针,但之前一直觉着这一块比较复杂,就一直没去仔细研究,终于有时间去仔细研究这一块内容了。

  • c风格的函数指针
  • 函数指针是指将一个函数赋值给一个变量的方法,可以将函数作为一个参数传递给另一个函数,简单的使用示例如下
  • #include <iostream>
    
    void PrintMessage()
    {
    	std::cout << "Hello World!" << std::endl;
    }
    
    int main()
    {
    	//一般情况下调用函数的方式
    	//PrintMessage();
    
    	//函数指针
    	//取一个函数的地址赋值给一个变量
    	auto function = PrintMessage;  //不加()
    	//函数就是cpu指令,当编译完成代码后,函数处在二进制文件的某个地方
    	//赋值给一个变量后可以向之前调用函数一样调用
    	function();
    	function(); //打印 "Hello World!"
    
    	std::cin.get();
    }
  • 上述示例中是通过auto来接收,接下来看一下PrintMessage具体的返回值类型。
  • #include <iostream>
    
    void PrintMessage()
    {
    	std::cout << "Hello World!" << std::endl;
    }
    
    int main()
    {
    	//一般情况下调用函数的方式
    	//PrintMessage();
    
    	//函数指针
    	//取一个函数的地址赋值给一个变量
    	auto function = PrintMessage;  //不加()
    	//函数就是cpu指令,当编译完成代码后,函数处在二进制文件的某个地方
    	//赋值给一个变量后可以向之前调用函数一样调用
    	function();
    	function(); //打印 "Hello World!"
    
    	//实际PrintMessage返回的类型是void(*function)()
    	//实际的类型是void(*)(),最后一个括号里面的放的是函数的参数类型,function是我们给这个返回类型起的名字
    	void(*pcop)();
    	pcop = PrintMessage;
    	pcop();//打印 "Hello World!"
    
    	//上述的void(*pcop)()可以使用typedef,将别名写在如下位置,看起来可能有点奇怪,但确实是这样的
    	typedef void(*testFunctionPoint)();
    
    	testFunctionPoint heiheihei = PrintMessage;
    	heiheihei();//打印 "Hello World!"
    
    	std::cin.get();
    }
  • 接下来展示函数指针的函数包含参数的示例
  • #include <iostream>
    
    void PrintMessage(int a)
    {
    	std::cout << "Hello World! " << a <<std::endl;
    }
    
    int main()
    {
    	//一般情况下调用函数的方式
    	//PrintMessage();
    
    	//函数指针
    	//取一个函数的地址赋值给一个变量
    	auto function = PrintMessage;  //不加()
    	//函数就是cpu指令,当编译完成代码后,函数处在二进制文件的某个地方
    	//赋值给一个变量后可以向之前调用函数一样调用
    	function(1);
    	function(2); //打印 "Hello World!"
    
    	//实际PrintMessage返回的类型是void(*function)()
    	//实际的类型是void(*)(),最后一个括号里面的放的是函数的参数类型,function是我们给这个返回类型起的名字
    	void(*pcop)(int);
    	pcop = PrintMessage;
    	pcop(5);//打印 "Hello World!"
    
    	//上述的void(*pcop)()可以使用typedef,将别名写在如下位置,看起来可能有点奇怪,但确实是这样的
    	typedef void(*testFunctionPoint)(int);
    
    	testFunctionPoint heiheihei = PrintMessage;
    	heiheihei(6);//打印 "Hello World!"
    
    	std::cin.get();
    }
  • 上述描述的都是函数指针的原理,接下来大概展示函数指针的使用场景。
  • #include <iostream>
    #include <vector>
    void PrintValue(int value)
    {
    	std::cout << value << std::endl;
    }
    
    void ForEach(const std::vector<int>& values, void(*func)(int))
    {
    	for (int value:values)
    	{
    		func(value);
    	}
    }
    
    int main()
    {
    	std::vector<int> values = {1,4,6,7,9};
    	//创建一个函数,迭代遍历values中的所有元素,并将值进行打印
    	ForEach(values, PrintValue);
    
    	std::cin.get();
    }
  • c++lambda表达式
  • lambda表达式是指用一种匿名函数的创建函数,用这种方式创建函数不需要实际创建一个函数。只要有一个函数指针,都可以使用lambda。接下来通过代码展示lambda。
  • 上述的代码展示的是用lambda替换上节所讲述的PrintValue函数指针。()中传入的是lambda的{}中所需的参数,上述的func(value)实际上调用就是[](int value){std::cout << value << std::endl;}。
  • 接下来事例展示将一个函数传递给一个API,以便在未来的某个时间,可以为我们调用这个函数,现在不能掉用该函数,因为函数所需要的数据还为准备好,所以需要延迟调用。lambda可以很好的实现上述需求,代码实现如下:
  • []里面放的是lambda的捕获,当需要将外部的变量传入lambda{}中时用到。
  • #include <iostream>
    #include <vector>
    #include <functional>
    
    void ForEach(std::vector<int> vlaues ,const std::function<void(int)>& func)
    {
        for(int value:vlaues)
            func(value);
    }
    
    int main()
    {
        std::vector<int> values = {2,5,7,9,4};
        int a = 10;
        //想要在lambda中调用main函数的a变量,直接调用会报错
        //可以通过[=]值传递进行调用,也可以通过[&]传递进行调用
        //此时ForEach中的参数如果是原始函数指针就会报错,需要改成function
        auto lambda = [=](int value){std::cout << value << a << std::endl;};
        ForEach(values, lambda);
        
    }
    
  • std::find_if,迭代器查找值
  • #include <iostream>
    #include <vector>
    #include <functional>
    #include <algorithm>
    
    void ForEach(std::vector<int> vlaues ,const std::function<void(int)>& func)
    {
        for(int value:vlaues)
            func(value);
    }
    
    int main()
    {
        std::vector<int> values = {2,5,7,9,4};
        //用find_if查找vector中第一个比3大的元素
        auto it = std::find_if(values.begin(),values.end(),[](int value){return value>3;} );
        std::cout << *it << std::endl;
        int a = 10;
        //想要在lambda中调用main函数的a变量,直接调用会报错
        //可以通过[=]值传递进行调用,也可以通过[&]传递进行调用
        //此时ForEach中的参数如果是原始函数指针就会报错,需要改成function
        auto lambda = [=](int value){std::cout << value << a << std::endl;};
        ForEach(values, lambda);
        
    }
    

文章来源:https://blog.csdn.net/qq_16701727/article/details/135527019
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。