type - C++ Lambdas:“可變”和“按引用捕獲”之間的區別



lambda c++用法 (1)

在C ++中,你可以像這樣聲明lambdas:

int x = 5;
auto a = [=]() mutable { ++x; std::cout << x << '\n'; };
auto b = [&]()         { ++x; std::cout << x << '\n'; };

兩個都讓我修改x ,那有什麼區別?


發生什麼事

第一個只會修改自己的x副本,並保持外部x不變。 第二個將修改外部x

嘗試每個後添加一個print語句:

a();
std::cout << x << "----\n";
b();
std::cout << x << '\n';

預計將印刷:

6
5
----
6
6

為什麼

可能有助於考慮lambda [...] expressions provide a concise way to create simple function objects (參見標準的[expr.prim.lambda])。

它們有一個公共內聯函數調用操作符[...] ,它被聲明為const成員函數,但僅當[...]當且僅當lambdaexpression的parameter-declaration-clause後面沒有mutable (斜體文本=標準中的引號)。

你可以想到

    int x = 5;
    auto a = [=]() mutable { ++x; std::cout << x << '\n'; };

==>

    int x = 5;

    class __lambda_a {
        int x;
    public:
        __lambda_a () : x($lookup-one-outer$::x) {}
        inline void operator() { ++x; std::cout << x << '\n'; }     
    } a;

    auto b = [&]()         { ++x; std::cout << x << '\n'; };

==>

    int x = 5;

    class __lambda_b {
        int &x;
    public:
        __lambda_b() : x($lookup-one-outer$::x) {}
        inline void operator() const { ++x; std::cout << x << '\n'; }         
        //                     ^^^^^
    } b;

問:但如果它是const函數,為什麼我還能改變x

答:你只是在改變外面的x 。 lambda自己的x是一個引用,而++x的操作不會修改引用 ,而是修改引用 的值

這是有效的,因為在C ++中,指針/引用的常量不會改變通過它看到的指針/引用的常量。





lambda