77 lines
2.2 KiB
Markdown
77 lines
2.2 KiB
Markdown
---
|
||
tags:
|
||
aliases:
|
||
date: 2022-06-12
|
||
time: 18:21:42
|
||
description:
|
||
---
|
||
|
||
一個簡單的 Lamdba 運算式:
|
||
```cpp
|
||
[] (int x, int y) -> bool {
|
||
return x < y;
|
||
}
|
||
```
|
||
|
||
- 以中括號開頭,中括號被稱為*lamdba 導入器(lamdba introducer)*
|
||
- 小括號裡面是*lamdba 參數列表(lambda parameter list)*
|
||
- 如果沒有參數,小括號可以省略,`[] () {...}` 可以簡寫成 `[] {...}`
|
||
- 箭號(`->`)後面是回傳的型別,如果沒寫就由 `return` 自動推斷
|
||
|
||
將 Lamdba 運算式指定給變數:
|
||
```cpp
|
||
auto comapre = [] (int x, int y) -> bool {
|
||
return x < y;
|
||
};
|
||
```
|
||
|
||
## Lamdba的擷取子句
|
||
以中括號開頭的 *lamdba 導入器*可以將外部的變數傳給 Lamdba 運算式,正式名稱是「擷取子句(capture clause)」。
|
||
`[=]` 表示它們會以值擷取(captured by value)。Scope內的變數都可以在
|
||
`[&]` 表示它們會以址擷取(captured by reference)。
|
||
|
||
### 以值擷取(captured by value)
|
||
假設有一段程式如下:
|
||
```cpp
|
||
void testLambda() {
|
||
float notUsed = 1.0f;
|
||
std::vector<int32_t> numlist{10, 20, 30, 50, 60};
|
||
auto findInRange = [=](int32_t start, int32_t end) {
|
||
for (auto num : numlist) {
|
||
if (num >= start && num <= end) return true;
|
||
}
|
||
return false;
|
||
};
|
||
|
||
std::cout << "Result: " << findInRange(25, 35) << "\n";
|
||
}
|
||
```
|
||
|
||
用`[=]`可以用來擷取 lamdba scope範圍所及的變數,沒有在 Lamdba 運算式裡面被用到的變數就不會被擷取,例如 `float notUsed = 1.0f;`。
|
||
另一個重點是:**被擷取的變數是不可以更改的**。例如,不能在lamdba裡面這樣寫:
|
||
```cpp
|
||
auto findInRange = [=](int32_t start, int32_t end) {
|
||
numlist.push_back(5); // ERROR!
|
||
|
||
for (auto num : numlist) {
|
||
if (num >= start && num <= end) return true;
|
||
}
|
||
return false;
|
||
};
|
||
```
|
||
|
||
如果一定要在 lambda內改變擷取的變數,那必須指名 lambda 為 `mutable`:
|
||
```cpp
|
||
auto findInRange = [=](int32_t start, int32_t end) mutable { // <-- assign mutable
|
||
numlist.push_back(5);
|
||
|
||
for (auto num : numlist) {
|
||
if (num >= start && num <= end) return true;
|
||
}
|
||
return false;
|
||
};
|
||
```
|
||
|
||
####
|
||
|
||
### 以址擷取(captured by reference) |