lambda表达式的一切

前言

  1. lambda表达式时C++11时引入的特性
  2. lambda又称匿名函数
  3. lambda本质是一个特殊的,匿名的类类型。它是一个带有operator()的类,即仿函数。
    • 仿函数(functor), 就是使得一个类的使用看上去像一个函数。其实现为类中实现一个operator(), 这个类就有了类似函数的行为,即为一个仿函数类。

lambda表达式的基本用法

[capture] (params) -> ret {body;};

  • capture 捕获列表
  • params 参数表
  • ret 返回值类型
  • body 函数体

捕获列表

  • []: 表示不捕获任何变量
  • [=]: 表示按值捕获变量
  • [&]: 表示按引用捕获变量

使用场景

函数体比较简单,由于作用域有限,最好是不在别的地方调用,这种场景下使用lambda可以省去函数的声明。

实验01 overload() to implement lambda

#include <iostream>
class AddNum {
    public:
        AddNum(int num): num_(num) {};

        // int addNum(int x) const {
        //     return num_ + x;
        // }

        int operator()(int x) const {
            return num_ + x;
        }
    private:
        int num_;
};

int main()
{
    /* functor */
    auto add_num = AddNum(10);
    /* auto x = add_num.addNum(5); */
    auto x = add_num(5);
    std::cout << "x: " << x << std::endl;

    /* lambda [] 中是 lambda的捕获列表 */
    /* lambda_num变量的作用域仅限于lambda表达式 */
    auto add_num2 = [lambda_num = 10](int x) {
        return lambda_num + x;
    };
    auto lambda_x = add_num2(5);
    std::cout << "lambda_x: " << lambda_x << std::endl;
}

编译并运行:

g++ lambda_01.cpp -std=c++17 && ./a.out

x: 15

lambda_x: 15

可以看到下方的lambda表达式所实现的效果与AddNum类重载()运算符后的效果相同。

实验02 store lambda to func

#include <iostream>

int main() {
    /* example 1 */
    int res = [](int x)->int {
        return ++x;
    }(3);

    std::cout << "res: " << res << std::endl;

    /* example 2, store it to func */
    /* we can use auto replace std::function */
    /* old: std::function<int(int)> func = [](int x)->int { */
    /* we can del retuen type int */
    /* old: auto func = [](int x)->int { */
    auto func = [](int x) {
        return ++x;
    };
    std::cout<<"i:";
    for (int i = 0; i < 10; i++) {
        std::cout << " " << func(i);
    }
    std::cout<<std::endl;
}

编译运行:

g++ lambda_02.cpp -std=c++17 && ./a.out

res: 4

i: 1 2 3 4 5 6 7 8 9 10

实验03 和for_each模板相结合,捕获

#include <iostream>
#include <algorithm>
#include <vector>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5, 6};
    int multiplier = 2;
    /* 按值捕获 eg1 */
    std::for_each(vec.begin(), vec.end(), [multiplier](int x){
        std::cout << x * multiplier << " ";
    });
    std::cout << std::endl;
    /* 按值捕获 eg2 use = instead*/
    std::for_each(vec.begin(), vec.end(), [=](int x){
        std::cout << x * multiplier << " ";
    });
    std::cout << std::endl;
    /* 按引用捕获 */
    std::for_each(vec.begin(), vec.end(), [&](int x){
        multiplier++;
        std::cout << x * multiplier << " ";
    });
    std::cout << std::endl;
}

编译并运行:

g++ lambda_03.cpp -std=c++17 && ./a.out

2 4 6 8 10 12

2 4 6 8 10 12

3 8 15 24 35 48

总结

  1. 判断lambda的使用场景
    • 关注作用域
    • 函数体少
  2. 捕获时注意是否需要捕获,若捕获是按值捕获还是按引用捕获

C++ lambda表达式(2)_哔哩哔哩_bilibili

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇