C ++ Lambdas:“mutable”并通过引用捕获 [英] C++ Lambdas: Difference between "mutable" and capture-by-reference

查看:306
本文介绍了C ++ Lambdas:“mutable”并通过引用捕获的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C ++中,可以像这样声明lambdas:

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

两者都允许我修改 x 是差别?

解决方案

发生了什么



只修改自己的 x 副本,并保留外部 x 不变。
第二个将修改外部 x



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

预计可打印:

  6 
5
----
6
6



为什么



这可能有助于考虑lambda [...]方法来创建简单的函数对象(参见标准的[expr.prim.lambda])。



。]一个公共内联函数调用操作符[...] ,它被声明为一个 const 成员函数,但只有 [...] if并且只有当lambdaexpression的 parameter-declaration-clause 后面没有 mutable (斜体文本=

  



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

==>

int x = 5;

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

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

==>

int x = 5;

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

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



/ strong>您只是更改外部 x 。 lambda自己的 x 是一个引用,操作 ++ x 不会修改引用,而是所引用的值



这是因为在C ++中,指针/引用的常量不会改变通过它看到的引号/引用的常量。


In C++ you can declare lambdas for example like this:

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

Both let me modify x, so what is the difference?

解决方案

What is happening

The first will only modify its own copy of x and leave the outside x unchanged. The second will modify the outside x.

Add a print statement after trying each:

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

This is expected to print:

6
5
----
6
6

Why

It may help to consider that lambda [...] expressions provide a concise way to create simple function objects (see [expr.prim.lambda] of the Standard).

They have [...] a public inline function call operator [...] which is declared as a const member function, but only [...] if and only if the lambdaexpression’s parameter-declaration-clause is not followed by mutable (italicized text = quotes from the standard).

You can think of as if

    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;

and

    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: But if it is a const function, why can I still change x?

A: You are only changing the outside x. The lambda's own x is a reference, and the operation ++x does not modify the reference, but the refered value.

This works because in C++, the constness of a pointer/reference does not change the constness of the pointee/referencee seen through it.

这篇关于C ++ Lambdas:“mutable”并通过引用捕获的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆