【C++】lambda表达式和正则表达式

引言

Lambda表达式是C++11引入的一种函数对象表示方式,它可以用于创建匿名函数并在需要函数对象的地方使用。Lambda表达式提供了一种简洁的方式来编写内联函数,特别适用于函数对象参数的传递、算法函数对象和并发编程中的回调函数。

内联函数是一种编译器优化技术,用于在编译时将函数的代码插入到调用点处,而不是通过函数调用的方式执行。这样可以避免函数调用的开销,提高代码的执行效率。

基本语法

[capture list] (parameters) -> return_type {
    
    
    // 函数体
}
  • capture list是一组被捕获的外部变量,用于在Lambda表达式中访问外部作用域的变量。它可以为空([])或包含一个或多个变量。
  • parameters是Lambda表达式的参数列表,与普通函数的参数列表类似。
  • return_type是返回类型,可以省略,编译器会自动推导返回类型。
  • {}中是Lambda表达式的函数体,可以包含任意有效的C++代码。

示例

#include <iostream>

int main() {
    
    
    int x = 5;
    int y = 10;

    // Lambda表达式示例
    auto sum = [](int a, int b) -> int {
    
    
        return a + b;
    };

    int result = sum(x, y);
    std::cout << "Sum: " << result << std::endl;

    return 0;
}

在上述代码中,我们定义了一个Lambda表达式sum,它接受两个整数参数并返回它们的和。使用auto关键字可以自动推导Lambda表达式的类型。在主函数中,我们调用Lambda表达式并输出结果。

捕获

捕获列表指定了 lambda 表达式所使用的外部变量,并控制了对这些变量的访问方式。

捕获列表包含一个或多个捕获项,每个捕获项由捕获标识符和捕获方式组成,用逗号分隔。捕获标识符可以是外部作用域的变量名、this 指针或通用的捕获符号(& 或 =)。

值捕获

使用捕获标识符以传值方式捕获变量。通过在捕获列表中使用变量名来实现。

int x = 5;
auto lambda = [x]() {
    
    
    // lambda 表达式的函数体,可以使用捕获的变量 x
};

引用捕获

使用捕获标识符以引用方式捕获变量。通过在捕获列表中使用变量名前加上 & 来实现。

int x = 5;
auto lambda = [&x]() {
    
    
    // lambda 表达式的函数体,可以使用捕获的变量 x,并修改它
};

隐式捕获

使用捕获符号 & 或 = 对外部作用域中的变量进行捕获。& 表示以引用方式捕获,= 表示以传值方式捕获。

int x = 5;
auto lambda1 = [&]() {
    
    
    // lambda 表达式的函数体,可以使用外部作用域的所有变量,并修改它们
};

auto lambda2 = [=]() {
    
    
    // lambda 表达式的函数体,可以使用外部作用域的所有变量,但不能修改它们
};

捕获对象

除了捕获变量之外,还可以在捕获列表中使用 this 指针来捕获当前对象。

class MyClass {
    
    
public:
    void func() {
    
    
        auto lambda = [this]() {
    
    
            // lambda 表达式的函数体,可以访问当前对象的成员变量和成员函数
        };
    }
};

扩展

mutable

正常情况下,捕获列表[]捕获到的参数是实参复制到形参的。对于一个值被拷贝的变量,lambda不会改变其值.如果我们希望能改变一个被捕获的变量的值,有以下两种方法:

  • 进行引用捕获,同一般引用一样,相当于别名。
  • 使用mutable关键字

mutable 是 C++ 中的一个关键字,用于修饰 lambda 表达式中的参数列表之后的函数体,表示该函数体中的成员变量可以被修改。

在 lambda 表达式中,默认情况下,lambda 是以 const 限定符来捕获外部的变量,这意味着 lambda 内部不能修改捕获的变量的值。然而,使用 mutable 关键字可以取消对变量的 const 限定,使得 lambda 内部可以修改捕获的变量。

#include <iostream>

int main() {
    
    
    int x = 5;

    auto lambda = [x]() mutable {
    
    
        x = 10; // 修改捕获的变量 x
        std::cout << "Inside lambda: x = " << x << std::endl;
    };

    lambda(); // 调用 lambda 表达式

    std::cout << "Outside lambda: x = " << x << std::endl;

    return 0;
}

在 lambda 内部,由于使用了 mutable 关键字,变量 x 的值可以被修改。在 lambda 外部,变量 x 的值保持不变。
注意:使用 mutable 关键字并不意味着一定要修改捕获的变量,它只是提供了在 lambda 内部修改变量的选项。

QT槽函数

在 Qt 中,槽函数是用于接收信号并处理相应事件的函数。传统的槽函数可以是普通成员函数、静态成员函数或全局函数。然而,Qt 5 引入了新的连接语法,允许将 lambda 表达式直接作为槽函数。
使用 lambda 表达式作为槽函数具有以下优点:

  • 不需要为每个槽函数创建独立的函数,可以在连接时直接编写处理逻辑。
  • 可以轻松访问和操作连接点附近的局部变量。
QPushButton button;
connect(&button, &QPushButton::clicked, [](){
    
    
    qDebug() << "Button clicked!";
});

在上述示例中,lambda 表达式 { … } 作为槽函数,用于处理按钮的点击事件。当按钮被点击时,lambda 表达式中的逻辑会被执行。

lambda表达式和普通函数区别

  • 匿名性:Lambda表达式是匿名的,没有函数名。它们可以直接在需要函数对象的地方定义和使用,而不需要显式地定义一个命名函数。
  • 语法简洁:Lambda表达式的语法相对简洁,可以用一行代码表示一个简单的函数对象。
  • 捕获外部变量:Lambda表达式可以捕获外部作用域的变量,即在Lambda表达式中访问外部变量。这使得Lambda表达式具有更灵活的上下文环境。
  • 类型推导:Lambda表达式使用auto关键字进行类型推导,使得代码更简洁,无需显式指定返回类型。
  • 内联函数:Lambda表达式常常用于内联函数的替代,可以直接在调用点定义函数对象,避免了函数调用的开销。
  • 函数对象传递:Lambda表达式可以作为参数传递给函数,用于回调函数或算法函数对象。

正则表达式

概述

正则表达式(Regular Expression),简称正则或正则式,是一种描述字符模式的工具。它可以用来匹配、查找、替换文本中符合特定模式的字符串。
正则表达式由字符和特殊符号组成,它们形成了一个模式,用于描述要匹配的字符串的规则。

正则表达式元字符

.:匹配任意单个字符,除了换行符。
*:匹配前一个元素零次或多次。
+:匹配前一个元素一次或多次。
?:匹配前一个元素零次或一次。
^:匹配字符串的开头。
$:匹配字符串的结尾。
\d:匹配一个数字字符。
\w:匹配一个字母、数字或下划线字符。
[…]:匹配方括号中的任意一个字符。
[^…]:匹配除了方括号中的字符之外的任意一个字符

猜你喜欢

转载自blog.csdn.net/qq_44878985/article/details/131142444