栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

Qt - Lambda表达式

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Qt - Lambda表达式

文章目录
  • Lambda 表达式
  • 语法格式
    • [capture]
      • 捕获表达式变量
      • 捕获作用域变量
    • (params)
    • mutable
    • constexpr
    • noexcept
    • ->return type
    • {}
  • Qt connect
  • 参考鸣谢

Lambda 表达式

Lambda 表达式是一个匿名函数。

这里从使用 std::sort 的写法看C++标准的发展:

ISO C++ 98 标准下,需要这样写:

bool compare(int& a,int& b)
{
    return a>b;
}

sort(a, a+n, compare);

而到了 ISO C++ 11 标准中引入 Lambda,代码将简洁很多:

sort(a, a+n, [](int a,int b){return a>b;});

ISO C++14 支持基于类型推断的泛型 Lambda 表达式,上面的代码可以改写为:

sort(a, a+n, [](const auto& a,const auto& b){return a>b;});

由于 Lambda 的类型是单一的,不能通过类型名来显式声明对应的对象,一般我们利用 auto 关键字和类型推导:

auto f = sort(a, a+n, [](const auto& a,const auto& b){return a>b;});
语法格式
[capture](params) mutable constexpr noexcept ->return type{statement}
[capture]

捕获列表,作用是将外部变量传入到 Lambda 表达式的内部,不可省略

捕获表达式变量

在 C++14 中引入了表达式捕捉,其允许用任何类型的表达式初始化捕捉的变量。

// 利用表达式捕获,可以更灵活地处理作用域内的变量
int x = 4;
auto y = [&r = x, x = x + 1] { r += 2; return x * x; }();
auto z = [str = "string"] { return str; }();

有时候你可以用 std::move 初始化变量。这对不能复制只能移动的对象很重要,比如 std::unique_ptr,因为其不支持复制操作,你无法以值方式捕捉到它。但是利用 Lambda捕捉表达式,可以通过移动来捕捉它:

auto myPi = std::make_unique(3.1415);
auto circle_area = [pi = std::move(myPi)](double r) { return *pi * r * r; };
cout << circle_area(1.0) << endl; 
捕获作用域变量
  • null,没有使用任何函数对象参数。

  • =,可使用Lambda所在作用域范围内的所有可见的局部变量,并才有值传递的方式传入。

  • &,可使用Lambda所在作用域范围内的所有可见的局部变量,并才有引用传递的方式传入。

  • this,可使用Lambda所在类内的成员变量。

  • variate,默认情况是const的,如果需要修改应加上mutable ;将variate以值传递形式传入。

  • &variate,将variate以引用传递的形式传入。

  • 组合,可用 ,隔开,例: [&, variate]

  • 包扩展

    template
    	void f(Args... args) {
        	auto x = [args...] { return g(args...); };
       	 x();
    }
    

注意点:

  • 引用捕获可用于修改外部变量,但值捕获不能。
  • 引用捕获会反映外部变量的更新,而值捕获则不会。
  • 引用捕获引入生存期依赖项,而值捕获却没有生存期依赖项。
(params)

参数列表,作用是将参数传入到 lambda 表达式内部,如果没有参数可省略。

auto y = [] (int first, int second)
{
    return first + second;
};

在C++14中,我们好可以使用auto,实现泛型:

auto y = [] (auto first, auto second)
{
    return first + second;
};
mutable

可变参数修饰符,默认情况下外部变量传入到 lambda 表达式内部后是 只读 的,mutable 的作用就是将 Lambda 表达式内部的只读变量变成 可读可写 的。

如果是值传入的方式,对传入变量的修改仅在Lambda内有效(值传递创建副本)。

mutable 也可以省略。

constexpr

C++11 提供了constexpr 让用户显式的声明函数或对象构造函数在编译器会成为 常数。

这个关键字明确的告诉编译器在编译时就去验证是否为常数。是一种比 const 更强的约束,这样可以得到更好的效率和安全性。

constexpr 也可省略。

noexcept

指定 Lambda 表达式可以抛出的异常,它可省略。

该关键字告诉编译器,函数中不会发生异常,这有利于编译器对程序做更多的优化。

如果 noexecpt函数 向外抛出了异常,程序会直接终止,调用 std::terminate() 函数,该函数内部会调用 std::abort() 终止程序。

注意:如果函数内部捕捉了异常并完成处理,这种情况不会继续向下抛出异常,即对noexecpt无法捕获该异常。

->return type

返回值, 如果 lambda 主体只包含一个返回语句,则可以省略 lambda 表达式的返回类型部分,编译器将自动推导。

auto x1 = [](int i){ return i; }; 
{}

函数执行体,和普通函数一样。

Qt connect

以 QPushButton 的 clicked 为例:

connect(btn, &QPushButton::clicked, [=](bool isChecked){
           qDebug() << "isChecked=" << isChecked;
       });
参考鸣谢

C++ 中的 Lambda 表达式

C++ 中的lambda表达式

Qt学习笔记(三):lambda 表达式

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/316464.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号