在 C++ 中,您可以像这样声明 lambdas:
int x = 5;
auto a = [=]() mutable { ++x; std::cout << x << '\n'; };
auto b = [&]() { ++x; std::cout << x << '\n'; };
两者都让我修改x
,那么有什么区别?
第一个只会修改自己的副本,x
而外部x
保持不变。第二个将修改外部x
。
在尝试每个之后添加一个打印语句:
a();
std::cout << x << "----\n";
b();
std::cout << x << '\n';
预计将打印:
6
5
----
6
6
考虑 lambda 可能会有所帮助
[...] 表达式提供了一种创建简单函数对象的简洁方法
(参见标准的 [expr.prim.lambda])
他们有
[...] 一个公共的内联函数调用运算符 [...]
它被声明为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;
问:但是如果是const
函数,为什么我还可以更改x
?
A:你只是在改变外面x
。lambda 自身x
是一个引用,操作++x
不会修改引用,而是引用的值。
这是因为在 C++ 中,指针/引用的常量不会改变通过它看到的指针/引用的常量。