add some comment

This commit is contained in:
johnwdjiang 2020-11-05 21:35:35 +08:00
parent b716af6b67
commit 264de26c9c

View File

@ -40,16 +40,16 @@ C++11中有两种默认的捕获模式按引用捕获和按值捕获。但按
按引用捕获会导致闭包中包含了对局部变量或者某个形参位于定义lambda的作用域的引用如果该lambda创建的闭包生命周期超过了局部变量或者参数的生命周期那么闭包中的引用将会变成悬空引用。举个例子假如我们有一个元素是过滤函数的容器该函数接受一个int作为参数并返回一个布尔值该布尔值的结果表示传入的值是否满足过滤条件。 按引用捕获会导致闭包中包含了对局部变量或者某个形参位于定义lambda的作用域的引用如果该lambda创建的闭包生命周期超过了局部变量或者参数的生命周期那么闭包中的引用将会变成悬空引用。举个例子假如我们有一个元素是过滤函数的容器该函数接受一个int作为参数并返回一个布尔值该布尔值的结果表示传入的值是否满足过滤条件。
```c++ ```c++
using FilterContainer = // see Item 9 for using FilterContainer = // see Item 9 for
std::vector<std::function<bool(int)>>; // "using", Item 2 std::vector<std::function<bool(int)>>; // "using", Item 2
// for std::function // for std::function
FilterContainer filters; // filtering funcs FilterContainer filters; // filtering funcs
``` ```
我们可以添加一个过滤器用来过滤掉5的倍数。 我们可以添加一个过滤器用来过滤掉5的倍数。
```c++ ```c++
filters.emplace_back( // see Item 42 for filters.emplace_back( // see Item 42 for
[](int value) { return value % 5 == 0; } // info on [](int value) { return value % 5 == 0; } // info on
); );
``` ```
@ -62,11 +62,11 @@ void addDivisorFilter()
auto calc1 = computeSomeValue1(); auto calc1 = computeSomeValue1();
auto calc2 = computeSomeValue2(); auto calc2 = computeSomeValue2();
auto divisor = computeDivisor(calc1, calc2); auto divisor = computeDivisor(calc1, calc2);
filters.emplace_back( // danger! filters.emplace_back( // danger!
[&](int value) { return value % divisor == 0; } // ref to [&](int value) { return value % divisor == 0; } // ref to
); // divisor ); // divisor
} // will } // will
// dangle! // dangle!
``` ```
这个代码实现是一个定时炸弹。lambda对局部变量divisor进行了引用但该变量的生命周期会在addDivisorFilter返回时结束刚好就是在语句filters.emplace_back返回之后因此该函数的本质就是容器添加完该函数就死亡了。使用这个filter会导致未定义行为这是由它被创建那一刻起就决定了的。 这个代码实现是一个定时炸弹。lambda对局部变量divisor进行了引用但该变量的生命周期会在addDivisorFilter返回时结束刚好就是在语句filters.emplace_back返回之后因此该函数的本质就是容器添加完该函数就死亡了。使用这个filter会导致未定义行为这是由它被创建那一刻起就决定了的。