C ++ Lambdas:“mutable”并通过引用捕获 [英] C++ Lambdas: Difference between "mutable" and capture-by-reference
问题描述
在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屋!