About
RSS

Bit Focus


C++ Lambda 简易上手

    本文所有代码示例通过 g++ 4.6 编译.

    之前有吐槽过 C++ STL 算法中的 for_each 函数华而不实, 主要原因是受限于 C++ 的函数编写语法, 即传统上 C++ 要求函数须独立编写, 而不能嵌套在其它函数内. 不过, 欢迎来到二十一世纪的第一个 0x10 年, 现在有了 lambda.
    与其它语言一样, C++ 的 lambda 就是个匿名函数, 它的语法结构如
[ 上下文变量绑定方式 ] ( 形式参数列表 ) 可省略的返回值类型声明
{
    函数体
}
    匿名函数可以定义在任何地方, 作为一个表达式出现; 如果在匿名函数的函数体中使用了表达式所在上下文中定义的量, 则需要指定绑定方式. 如
// 定义变量 sqr 为一个匿名函数
// 这个匿名函数的上下文变量绑定方式为空, 因为它无须引入任何上下文变量
// 这个匿名函数接受一个 int 作为参数
// 返回值类型声明省略, 由编译器推倒出返回 int
auto sqr = [](int x)
           {
               return x * x;
           };

int x = 10;
// 这个匿名函数的上下文变量绑定方式为 & 即引用方式, 它引用了上文中定义的 x
// 这个匿名函数接受一个 int 作为参数
// 返回值类型声明为 bool
auto equalsToX = [&](int y) -> bool
                 {
                     return x == y;
                 };

// 这个匿名函数的上下文变量绑定方式为 = 即复制方式, 它引用了上文中定义的 x
// 这个匿名函数接受一个 int 作为参数
// 返回值类型声明省略
auto lessThanX = [=](int y)
                 {
                     return y < x;
                 };
    可见多亏了 C++ 的强制类型声明和变量定义检查, 才把一个简单的匿名函数搞得这么复杂, 解决了不少其它语言中不存在的问题.

    作为 C++ 程序员的一个特异能力便是能够在写代码时就预见到这段程序运行时内存与对象的流动. 看了上面匿名函数的各种奇葩绑定上下文的方法, 很明显它们不仅是一个函数那么简单, 如果必要匿名函数会占用一些内存空间, 可以做这样一个实验来试试.
struct Point {
    Point()
        : x(0)
        , y(0)
    {}

    double x;
    double y;
};

int main()
{
    Point p;
    auto f = [&]()
             {
                 std::cout << p.x << "," << p.y << std::endl;
             };
    auto g = [=]()
             {
                 std::cout << p.x << "," << p.y << std::endl;
             };
    std::cout << sizeof(f) << " - " << sizeof(Point*) << std::endl;
    std::cout << sizeof(g) << " - " << sizeof(Point) << std::endl;

    auto sqr = [](int x)
               {
                   return x * x;
               };
    std::cout << sizeof(sqr) << std::endl;

    return 0;
}

Permanent Link: /p/505 Load full text

Post tags:

 Labmda
 C++
 C++11
 Nested Function


. Back to Bit Focus
NijiPress - Copyright (C) Neuron Teckid @ Bit Focus
About this site