Callable 可调用对象 lambda表达式 “匿名函数“

射频工程师笔记---射频通信基础 回顾一下移动通信技术的发展,其实是互联网和通信技术的融合过程。在这个过程中,很多应用都在不断加入其中。比如计算机跟通信的融合产生了互联网、互联网跟手机的融合带来了移动互联网。手机可以看杂志、看视频、听音乐,于是又出现了内容服务产业;再后来,电视音箱等设备也能联网,于是网络跟家电又产生了融合。所以应用的出现总是在融合其他产业。在1995年,比尔·盖茨在《未来之路》一书中首次提出:在未来... 阅读详情

1)什么是可调用对象? 

        Callable 可调用对象 支持函数调用运算符() 

        在C++中, Callable可调用对象有如下: 
                (1) 函数    
                (2) 函数指针 
                (3) 函数对象 functor "仿函数"   
                        只要该对象所属的类,实现了 函数调用运算符重载 operator() 
                (4) lambda表达式

例子: 

template<typename T>
void Swap( T& a, T& b )
{
    T tmp = a;
    a = b;
    b = tmp;
}

//冒泡排序 
template<typename T, typename Caller>
void MPsort( T *begin, T *end, Caller less )  
//less类似于一个函数 bool (T& a, T& b)
{
    T *p = end-1;

    for( ; begin < end ; begin++ )
    {
        for( p=end-1; p>begin; p-- )
        {
            //if( *p < *(p-1) )
            if( less(*p, *(p-1)) )
            {
                //交换位置
                Swap( *p, *(p-1) );
            }
        }
    }
}

bool pk( const int& a, const int& b)
{
    return a<b;
}

class Less
{
public:
    // () 函数调用运算符重载
    bool operator()( const int& a, const int& b )
    {
        return a<b;
    }
};

int main()
{
    int a[10] = {1,3,5,7,9,2,4,6,8,0};
    MPsort( a, a+10 );	// [ , )

    //1.函数 
    //pk是一个函数,pk后面可以接(), 因此pk就是一个Callable
        MPsort( a, a+10, pk );

    //2.函数指针
        bool (*p)(const int& , const int&);
        p = pk;
        MPsort( a, a+10, p );	//函数指针p 也是一个Callable

    //3.函数对象 functor "仿函数"
        Less less;	//函数对象, 也是一个Callable
        MPsort( a, a+10, less );
    
    //4.lambda表达式,也是一个Callable
        //...

    for( auto &s : a )
    {
        cout << s << " ";
    }
    cout << endl;
}

lambda表达式 被用来表示一种匿名的函数
所谓的匿名函数,简单的理解就是 没有名字的函数, 也常称为: lambda表达式 / lambda函数 

lambda匿名函数 的定义语法: 
[外部变量的访问方式的说明符] (形式参数) mutable noexcept/throw() -> 返回值类型 
{
//...  函数体/语句 
}

(1) [外部变量的访问方式的说明符]
        []不能省略
        []中括号 用于向编译器表明是一个lambda表达式
        []中括号内部 可以注明当前lambda函数的函数体中,可以使用哪些"外部变量"
            "外部变量",指的是 和 lambda表达式 位于同一个作用域内的所有的局部变量
        [] 用于向编译器表明,该匿名函数需要"捕获"哪些外部变量 
            lambda引入"外部变量"的方式 
                []  空, 表示当前的lambda匿名函数不导入任何的外部变量
                [=] 只有一个=等于号,表示是以值传递的方式导入所有的外部变量
                [&] 只有&引用符号,表示以 引用传递的方式导入所有的外部变量 
                [val1, val2, ...] 表示以值传递的方式导入val1,val2等指定的多个外部变量,顺序无关 
                值传递的方式捕获外部变量,会在定义lambda表达式时,生成它的一个拷贝


                [&val1, &val2, &...] 表示以引用传递的方式导入val1,val2等指定的多个外部变量,
                [ val1, &val2, ... ] 表示以值传递的方式导入val1, 以引用传递的方式导入val2 
                [=, &val1]  除了val1是引用传递的方式导入以外,其他的都是值传递的方式导入
                [this] 表示以值传递的方式导入当前的this指针 

                    // [=, val1]   //error 单个变量不允许以相同的传递方式导入多次 

(2) (形式参数) 
    和普通函数的定义一样, lambda函数也可以接收外部传递过来的多个参数
        和普通函数不同的是: 
            如果不需要传递参数, 连同()小括号一起省略

(3) mutable 
    "可变的", 此关键字可以省略, 如果使用了 则之前的()就不能省略了 
    默认情况下: 
        对于以值传递的方式导入的外部变量,不运行来lambda函数体内修改它们的值 
                (可以理解为 这部分变量都是 const常量 )
        如果想修改它们,则必须使用 mutable这个关键字
    注意: 
        对于以值传递的方式引入的外部变量,lambda表达式修改的只是拷贝的那一份 
        并不会修改真正的外部变量 

(4) noexcept/throw() 
    可省略的, 如果使用了 则之前的()就不能省略了

    noexcept 表示匿名函数体内不会抛出异常, 默认情况下(不加noexcept) 匿名函数体内可以抛出异常的
    throw() 用来指定函数体内抛出的异常的类型

(5) -> 返回值类型 
    指定匿名函数的返回值类型 
        如果lambda函数体内只有一个return语句,或者该函数返回值为void 
        则编译器可以自行推断返回值类型,在这种情况下 可以直接省略 

(6) 函数体 
    和普通函数一样, lambda匿名函数包含的代码都必须放在函数体内 
    该函数体内 除了可以使用自己定义的内部变量(包括参数), 还可以直接使用引入的外部变量
    当然也可以使用全局变量 

lambda表达式可以 形成一个 "闭包" ,可以捕获外部变量或对象 

例子: 
    // 4.lambda表达式 , 也是一个Callable可调用对象

MPsort( a, a+10, [](const int& a, const int& b) -> bool { return a < b; }  );


MPsort( a, a+10, [](const int& a, const int& b) { return a < b; }  );

C++11开始引入的可调用对象的其他形式,如std::bind的结果和std::function的实例。

5. std::bind
std::bind用于绑定一个可调用对象的参数,并返回一个新的可调用对象。

#include <iostream>  
#include <functional>  
  
// 普通函数  
void print_sum(int a, int b) {  
    std::cout << a + b << std::endl;  
}  
  
int main() {  
    // 使用std::bind绑定print_sum的第一个参数为10  
    auto bound_print_sum = std::bind(print_sum, 10, std::placeholders::_1);  
      
    // 调用bound_print_sum,只需提供一个参数  
    bound_print_sum(5); // 输出15  
      
    return 0;  
}


6. std::function
std::function是一个通用的、多态的函数封装器。它可以存储、复制和调用任何可调用对象,如函数、lambda表达式、函数对象或其他std::function对象。
 

#include <iostream>  
#include <functional>  
#include <vector>  
#include <algorithm>  
  
int main() {  
    std::vector<int> numbers = {1, 2, 3, 4, 5};  
      
    // 使用std::function来存储任何可调用对象  
    std::function<int(int)> operation;  
      
    // 赋值一个lambda表达式给operation  
    operation = [](intn) { return n * n; };

// 使用std::transform和std::function来将每个数平方
std::transform(numbers.begin(), numbers.end(), numbers.begin(), operation);

// 输出结果
for (int n : numbers) {
    std::cout << n << ' ';
}
std::cout << std::endl;

// 更改operation以指向另一个可调用对象
operation = [](int n) { return n * 3; };

// 再次使用std::transform来将每个数乘以3
std::transform(numbers.begin(), numbers.end(), numbers.begin(), operation);

// 输出结果
for (int n : numbers) {
    std::cout << n << ' ';
}
std::cout << std::endl;

return 0;
}

        在这个例子中,`std::function<int(int)>`表示一个接受一个`int`参数并返回`int`的可调用对象。我们首先将一个lambda表达式赋值给`operation`,然后使用它来计算每个数的平方。接着,我们更改`operation`以指向另一个lambda表达式,这次我们将每个数乘以3。 每种可调用对象都有其适用的场景。函数和函数指针简单直接,适用于简单的函数调用。Lambda表达式提供了匿名函数和捕获局部变量的能力,非常灵活。函数对象(仿函数)允许你封装更复杂的逻辑,并可以像使用对象一样使用它们。

        `std::bind`和`std::function`提供了更高级的功能,如参数绑定和可调用对象的类型擦除,使得代码更加通用和灵活。 

我的GIT练习ONE Git 是一个分布式版本控制及源代码管理工具;Git 可以为你的项目保存若干快照,以此来对整个项目进行版本管理每一次的练习,都是对自身知识的巩固,以及对自身知识的一个测试。 阅读详情

相关推荐

PVE(Proxmox VE)添加VMware Esxi并迁移虚拟机

跨平台迁移虚拟机:从VMware虚拟化平台迁移虚拟机到PVE平台。

VEGETA的博客 7712

【Java 8 新特性】Java 8 Runnable和Callable使用Lambda表达式示例(带参数)

Java 8 Runnable和Callable使用Lambda表达式示例Java 8 Runnable Lambda示例(带参数)Java 8 Callable Lambda示例(带参数)参考文献 在Java 8中,Runnable和Callable两个接口均已通过@FunctionalInterface进行注释。 我们可以使用lambda表达式实现run()和call()方法。 在此页面上,我们还将提供如何将参数传递给Runnable和Callable方法。 Java 8 Runnable Lambda

猫巳的博客 8006

Hopf振荡器在机器人步态控制里到底怎么用?一个CPG仿生案例说清楚

本文深入解析了Hopf振荡器在机器人步态控制中的实际应用,通过CPG仿生案例详细展示了从数学方程到关节指令的完整流程。重点探讨了Hopf振荡器的极限环稳定性、参数调节技巧及自适应控制策略,为机器人运动控制提供了高效解决方案。

weixin_29284657的博客 200

Lambda 表达式详解

Lambda表达式,也可称为闭包,它是推动Java8发布的最重要新特性。Lambda表达式可以取代大部分的匿名内部类,写出更优雅的Java代码,可以极大地优化代码结构。JDK1.8也提供了大量的内置函数式接口供我们使用,使得Lambda表达式的运用更加方便、高效。Lambda表达式的加入,使得Java拥有了函数式编程的能力。在其它语言中,Lambda表达式的类型是一个函数;但在Java中,Lambda表达式被表示为对象,因此它们必须绑定到被称为接口的特定对象类型。​.........

Loser顾 712

【HCIA学习记录】WLAN配置实验

HCIA-WLAN

寸先生的AI道路 3872

统信UOS专业版服务器无人值守安装

(2)、专业版:主要针对整机厂商、政府单位、事业单位和企业用户使用,cpu目前支持x86、arm、mips、sw64和LoogngArch架构,试用期免费获得90天的使用,随后需要单位采购授权,获得正式激活码后才可以正常使用。其中企业版代号为d,行业版为a/c,欧拉版则为e,在最近的更新中,c版已经停止更新迭代,后续行业版本将都为a版,版本代号体现在镜像名字中以及版本号上,例如1050d则表示企业版1050版本。UOS系统服务器版本分为:专业版(d版)、行业版(a版)、欧拉版(e版)

靠谱运维 2250

多线程——Callable接口,lambda

Callable接口,lambda表达式

yfq_29的博客 575

64.企业级案例(上)-金融行业DDD落地全流程支付系统-附架构演进图

本文以金融支付系统为例,完整展示了DDD在企业级项目中的落地流程。首先通过事件风暴识别核心业务领域,包括交易、渠道、账务等限界上下文。在战略设计中划分上下文边界,确定交易上下文为核心域。战术设计聚焦交易上下文,详细设计了支付单聚合、值对象和支付路由服务。架构实现采用CQRS+EDA模式,通过命令端处理交易,查询端异步更新读模型,并利用防腐层隔离外部渠道。案例展示了DDD从业务探索到架构实现的全过程,体现了其在复杂业务系统中的价值。

yonggeit的博客 3035

线程的创建、Lambda函数式接口?Runnable和Callable之间的适配?动态修改线程任务?这里带你图解Java线程池

线程池,总算是搞懂了,所谓的核心线程数,只是一个定界指针,而线程存活时间也是靠按照时间来获取任务来实现的。而任务的执行,并不是靠更换线程的仍无,仍然是靠new线程, 当执行完了以后进行processWorkerExit()进行释放同时大家也可以看到,这里面的阻塞队列,有多种实现,具体的各种实现我们下期再谈。线程池-腾讯云开发者社区-腾讯云 (tencent.com)java工程师要会的大数据之Stream流-腾讯云开发者社区-腾讯云 (tencent.com)

Karos的博客 582

15.1-缓存调试解析

摘要:DSU-120提供L3缓存和监听过滤器(SF)RAM的调试功能,通过CLUSTERCDBG寄存器控制访问。该功能需在集群ON电源模式下使用,且需确保单核访问。寄存器位字段根据读写操作不同,可配置WAY、RAM类型等参数。数据读取分为监听过滤器RAM、标签RAM、数据RAM及MTE标签四种类型,各有特定的位字段解释。配置参数包括切片ID宽度、标签索引宽度等,随缓存大小变化。

baron-周贺贺-代码改变世界ctw 110

【2025年华为秋招(AI)-11月19日-第二题(200分)- 终端款型聚类识别】(题目+思路+Java&C++&Python解析+在线测试)

该摘要总结了题目要求、输入输出格式、KMeans算法的实现步骤以及关键点。以下是150字内的摘要: 本文提出基于KMeans算法对终端型号进行聚类的方法。通过包间隔时长、连接持续时长、漫游前后信号强度4个特征,使用欧氏距离度量相似度。算法采用固定初始化策略(前k个样本作为初始质心),经过分配-更新迭代,直至质心移动小于1e-8或达到最大迭代次数。最终输出各簇样本数并按升序排列,解决了终端型号自动分类问题。示例显示该方法能有效识别3-4类终端,并准确统计每类数量。

m0_73659489的博客 141

Callable用lambda写法

Callable<JSONObject> jsonObjectSupplier = () -> JSON.parseObject(s); 可以这么写,也可以进行封装 @Nullable public static <T> T tryCall(Callable<T> callable) { try { return callable.call(); } catch (Throwable e) { return n.

weixin_42180169的博客 1044

基于Simulink的光储系统黑启动能力仿真

本文基于Simulink平台构建了光储系统黑启动仿真模型,详细阐述了储能VF控制、光伏孤岛MPPT和同步并网等核心控制策略。通过分阶段协调控制(储能启动→关键负载→光伏接入→非关键负载→同步并网),实现了60秒内恢复供电、母线电压波动<5%的性能指标。仿真结果表明,协调控制策略相比无序启动可显著提升系统稳定性,避免电压崩溃和负载跳闸。文章还提供了完整的建模步骤、核心代码及进阶优化方向,为微电网应急供电设计提供了实用参考。该模型适用于光伏储能系统的黑启动能力验证和优化研究。

amy_mhd的博客 106

【c++】可调用对象(Callable Objects)

c++11中有一个重要的概念叫做可调用对象(Callable Objects)。 总的来说,可调用对象可以是以下几种情况: 普通函数 函数指针 仿函数,即重载了operator()运算符的类对象 匿名函数,即Lambda表达式 std::function 文章目录1.普通函数2.函数指针3.仿函数4. 匿名函数(Lambda表达式)4.1 定义4.2 例子4.3 隐式捕获5. std::fu...

qq_43145072的博客 6032

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

C++可调用Callable类型的总结

可调用(Callable) 类型是可应用 INVOKE 操作(std::invoke 是在 C++17 里定义的类, 感觉意思就是执行函数操作的模板类.)

红军不怕远征难,万水千山只等闲 1836

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

【函数式编程实战】(三)Lambda表达式原理与函数式接口精讲

本文讲解lambda表达式语法、语义,讲解函数式接口是什么,作用是什么,Lambda表达式的编译原理,以及Java8及高版本的函数式接口Consumer、Function 、Predicate,将会在工作中大量用到

小明的Java问道之路 2756

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

python定义匿名函数关键字_python语言的匿名函数、7种可调用对象以及用户定义的可调用类型...

匿名函数在python表达式中,用来创建匿名函数的是lambda关键字。lambda函数在python语言中只能使用纯表达式,也就是说,在lambda函数体中不能使用while和try,当然也不能赋值等python语句。实际应用过程中,lambda函数最适合在参数列表中使用。下面我们来看胰腺癌例子,使用lambda函数表达式反转拼写,然后依据发转的结果对其进行排序,具体如下所示:那么,是不是意味着...

weixin_39603505的博客 237

C++11:lambda表达式,包装器

C++11:lambda表达式,包装器

2401_88433210的博客 1287

一文搞懂Lambda表达式与函数对象(现代C++的“灵活编程工具”)

摘要: Lambda表达式与函数对象是C++中实现灵活编程的核心工具。函数对象(仿函数)通过重载operator()实现类实例的可调用行为,能携带状态但语法繁琐;Lambda作为语法糖,本质是编译器生成的匿名函数对象,通过简洁语法(捕获列表、参数列表、函数体)实现上下文变量捕获与逻辑封装,尤其适合STL算法回调等临时场景。两者各有侧重:函数对象适合复杂、可复用的逻辑,Lambda则以简洁性见长,但需注意引用捕获的生命周期风险。合理选择二者可提升代码效率与可维护性。

I Promise的博客 627

【C++】C++11新特性—可变参数模版、lambda、包装器

可变参数模板、lambda表达式、包装器等。在lambda函数定义中,参数列表和返回值类型都是可选部分,而捕捉列表和函数体可以为空。因此C++11中最简单的lambda函数为:[]{}; 该lambda函数不能做任何事情。

小羊的博客 2180

C++ 可调用对象 (Callable Object)

capture list 捕获列表是一个lambda 所在函数中定义的局部变量的列表。一个lambda 表达式代表一个可调用的代码单元,可以将其理解成一个匿名的内联函数。如果忽略了返回类型,lambda 表达式会根据代码推断出返回类型。可以忽略参数列表和返回类型,但必须有捕获列表和函数题。谓词 predicate, 即标准库算法传递的参数。

JeffTech的专栏 295

三:Lambda表达式

本章内容 Lambda管中窥豹 在哪里以及如何使用Lambda 环绕执行模式 函数式接口,类型推断 方法引用 Lambda复合 1. lambda管中窥豹 1.1 可以把Lambda表达式理解为简洁地表示可传递的匿名函数的一种方式:它没有名称,但它 有参数列表、函数主体、返回类型,可能还有一个可以抛出的异常列表。这个定义够大的,让我 们慢慢道来。 匿名——我们说匿名,是因为它不像普通的方法...

qq_39022311的博客 1655

python dll 调用 方法未找到_python知识分享:匿名函数、7种可调用对象和定义可调用类型方法...

#python打卡##Python数学编程##python#匿名函数在python表达式中,用来创建匿名函数的是lambda关键字。lambda函数在python语言中只能使用纯表达式,也就是说,在lambda函数体中不能使用while和try,当然也不能赋值等python语句。实际应用过程中,lambda函数最适合在参数列表中使用。下面我们来看胰腺癌例子,使用lambda函数表达式反转拼写,然后...

weixin_39833469的博客 98

2019.5.4_全神贯注,心无旁骛_ 匿名函数

舒给我发了她去浪的照片,颜值满分! 摘自《流畅的Python》 匿名函数 lambda关键字在Python表达式内创建匿名函数 然而,Python简单的句法限制了lambda函数的定义体只能使用纯表达式。换句话说,lambda函数的定义体中不能赋值,也不能使用while和try等Python语句。 在参数列表中最适合使用匿名函数。例如,如下实例,使用lambda表达式重写了昨天的排序押韵单词的示...

weixin_33978016的博客 122

小知识 - Anonymous new Runnable() can be replaced with lambda more…

来友链呀: Roc's Blog 一直在做 Java 后端开发,很少手动的去写线程了,今天在复习 ThreadPool 的时候,发现了一个提示: Anonymous new Runnable() can be replaced with lambda. 匿名的创建 Runnable 可以被 Lambda 替换。那肯定要紧追 Lambda 的步伐呀。 【注】在Java 1.7或更早的jv...

一只奋斗的猪 6983

Java8 Lambda 表达式

可参考博文: http://blog.youkuaiyun.com/codejas/article/details/78810719 在学习Lambda 之前可以先了解一下java8 中关于接口的变化,以及函数式接口的定义及作用。 (一)Lambda 表达式介绍与语法格式 1.1Lambda 介绍 Lambda 是一个匿名函数,我们可以把 Lambda表达式理解为是一段可以传递的代码(将代码像数据一样进...

qq_11716的博客 127
上一篇: 头文件中声明static修饰的函数为什么能在其他源文件中使用
下一篇: 一文详解类的静态成员
思路可以啊
博客等级 码龄6年 91粉丝 16原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值