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