C++ Lambdas:"mutable"和按引用捕获之间的区别

C++ Lambdas: Difference between "mutable" and capture-by-reference

本文关键字:之间 引用 区别 Lambdas mutable C++      更新时间:2023-10-16

在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

可能有所帮助

[…]表达式提供了一种简洁的方式来创建简单的函数对象

<一口>(见[expr.prim。

他们有

[…一个公共内联函数调用操作符[…]

被声明为const成员函数,但只有

[…]当且仅当lambda表达式的参数声明子句后面没有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;

Q:但是如果它是const函数,为什么我仍然可以更改x ?

A:您只更改外部x 。lambda自身的x是一个引用,操作++x不会修改引用,而是修改被引用的值

这是有效的,因为在c++中,指针/引用的constness不会改变通过它看到的指针/引用的constness。