首页 > 代码库 > C++14 lambda 简介

C++14 lambda 简介

C++ 的最新版本,C++14 于2014年8月通过了。C++14 带来了一些期待已久的变化,比如auto类型可以作为函数返回值类型,通用的lambda表达式——也是本篇文章的主题。

C++ 中的 lambda,在 C++11 标准中就有介绍。主要是为了书写更简洁,还有就是匿名函数用以代替函数对象,避免单独创建一个 class 和一个函数定义。这里有一个 C++11 lambda 用法的典型例子:返回一个数的平方。

int result = [](int input) {return input * input; }(10);
cout<< result << endl;
如果你想在多个地方复用这段代码,你可以将这个函数保存在一个变量里:

auto func = [](int input) { return input * input; };

// first use
std::cout << func(10) << std::endl;

// second use
std::cout << func(23) << std::endl;

你能看到上面代码中的问题吗?它只能用于计算一个integer数的平方。然而,我们想让这个 lambda 表达式应用于 double 类型或是用于一个 complex 数字。我们想要的是下面的这些:

// square of an int
std::cout << func(10) << std::endl;

// square of a double
std::cout << func(2.345) << std::endl;

// square of a complex number
std::cout << func(std::complex<double>(3, -2)) << std::endl;
显然,我们可以用函数模板:

template <typename T>
T func(T z) {
    return z * z;
}
然而,定义一个有名的、全局的函数的方法不是我们本篇文章要讲的,C++14 标准介绍了通用化的 lambda 表达式,允许我们用 auto 来作为一个 lambda 表达式的参数类型。我们可以写一段更简洁、更优雅的代码:

auto func = [](auto input) { return input * input; };
下面是上面这个例子的完整的程序:

#include<iostream>
#include<complex>

int main() {
    // Store a generalized lambda, that squares a number, in a variable
    auto func = [](auto input) { return input * input; };

    // Usage examples:
    // square of an int
    std::cout << func(10) << std::endl;

    // square of a double
    std::cout << func(2.345) << std::endl;

    // square of a complex number
    std::cout << func(std::complex<double>(3, -2)) << std::endl;

    return 0;
}
上面的代码可以用现在的 C++ 编译器编译,比如:GCC 4.9.x 或 Clang。下面是用 Clang 、GCC 编译以及运行结果:

$ clang++ -std=c++1y -pedantic -Wall -stdlib=libc++ test_01.cpp -o test_01
$ ./test_01
100
5.49903
(5,-12)
$ g++-4.9.1 -std=c++14 -pedantic -Wall test_01.cpp -o test_01
$ ./test_01
100
5.49903
(5,-12)
$

然而,lambda 表达式在 STL 中也有很多闪光点。如果我们想将一个 vector 中的数字按降序排列,我们可以这样用 lambda 表达式:

std::sort(V.begin(), V.end(), [](auto i, auto j) { return (i > j); });
下面是一个完整的用 lambda 实现对有10个 integer 数字的 vector 进行降序排序的程序:

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

int main() {
    std::vector<int> V(10);
    
    // Use std::iota to create a sequence of integers 0, 1, ...
    std::iota(V.begin(), V.end(), 1);
    
    // Print the unsorted data using std::for_each and a lambda
    std::cout << "Original data" << std::endl;
    std::for_each(V.begin(), V.end(), [](auto i) { std::cout << i << " "; });
    std::cout << std::endl;

    // Sort the data using std::sort and a lambda
    std::sort(V.begin(), V.end(), [](auto i, auto j) { return (i > j); });
    
    // Print the sorted data using std::for_each and a lambda
    std::cout << "Sorted data" << std::endl;
    std::for_each(V.begin(), V.end(), [](auto i) { std::cout << i << " "; });
    std::cout << std::endl;

    return 0;
}
下面是上面程序的运行结果:

$ g++-4.9.1 -std=c++14 -pedantic -Wall test_02.cpp -o test_02
$ ./test_02
Original data
1 2 3 4 5 6 7 8 9 10
Sorted data
10 9 8 7 6 5 4 3 2 1
$

如果你有兴趣了解 C++11 语法,那么我推荐你读这本书:jarne Stroustrup 的 《The C++ Programming Language》,或是这本:《Professional C++》



原文链接:https://solarianprogrammer.com/2014/08/28/cpp-14-lambda-tutorial/

C++14 lambda 简介