参考这个线程:https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0806r2.html https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0806r2.html
It says:
换句话说,一个默认捕获 ([&]) 以拼写出冗余的方式捕获 *this,但另一个捕获 ([=]) 以非冗余方式捕获它。
这表示在 c++17 之前, [=] 捕获this
作为值,并且 [&] 将捕获 [*this],这是不明确的。所以我进行了一个快速测试,看看 [&] 是否默认捕获 [*this]。
我的测试代码尝试查看 [&] 是否默认捕获 *this,然后应该调用复制构造函数,并且对其值的任何更改都不会影响原始对象,因为它是副本。
#include<iostream>
using namespace std;
class M{
int mI;
public:
M() : mI(3) { cout << "ctor\n"; }
~M() { cout << "dtor\n"; }
M(const M& m) {
if (this != &m) {
cout << "copy ctor\n";
mI = m.mI;
}
}
M& operator=(const M& m) {
if (this != &m) {
cout << "operator =\n";
mI = m.mI;
}
return *this;
}
void CaptureByValue() {
auto f1 = [=] () { // capture this
cout << mI << '\n';
++(this->mI);
};
f1();
cout << mI << '\n';
}
void CaptureByReference() {
auto f1 = [&] () { // capture *this
cout << mI << '\n';
++(this->mI);
};
f1();
cout << mI << '\n';
}
};
int main() {
{
M obj1;
obj1.CaptureByValue();
}
cout << "------------\n";
{
M obj2;
obj2.CaptureByReference();
}
return 0;
}
编译并运行它:
clang++ LambdaCapture.cpp -std=c++11 && ./a.out
clang++ LambdaCapture.cpp -std=c++14 && ./a.out
clang++ LambdaCapture.cpp -std=c++17 && ./a.out
所有案例打印:
ctor
3
4
dtor
------------
ctor
3
4
dtor
我的问题:
(1)结果出乎我的意料:没有调用任何copyctorCaptureByReference
并且更改的值会影响原始值this
目的。测试代码没有促进 cpp17 中的 lambda 语法更改。
(2) 我什至无法将捕获更改为 [=, *this] 或 [&, *this],因为编译器会说:
LambdaCapture.cpp:25:13: error: read-only variable is not assignable
++(this->mI);
^ ~~~~~~~~~~
很奇怪,怎么出来的read-only
这里的变量,至于this
指针。
感谢您的解释。