[] | Пустой список захвата. Лямбда-выражение не может использовать переменные из содержащей функции. Лямбда-выражение может использовать локальные переменные, только если оно захватывает их |
[ | — разделяемый запятыми список имен, локальных для содержащей функции. По умолчанию переменные в списке захвата копируются. Имя, которому предшествует знак &, захватывается по ссылке |
[&] | Неявный захват по ссылке. Сущности из содержащей функции используются в теле лямбда-выражения по ссылке |
[=] | Неявный захват по значению. Сущности из содержащей функции используются в теле лямбда-выражения как копии |
[&, | — разделяемый запятыми список любого количества переменных из содержащей функции. Эти переменные захватываются по значению; любые неявно захваченные переменные захватывается по ссылке. Именам в списке не могут предшествовать символы & |
[=, | Переменные, включенные в список , захватываются по ссылке; любые неявно захваченные переменные захватывается по значению. Имена в списке не могут включать часть this и должны предваряться символом & |
Можно также определять лямбда-выражения, захватывающие переменные по ссылке. Например:
void fcn2() {
size_t v1 = 42; //
//
auto f2 = [&v1] { return v1; };
v1 = 0;
auto j = f2(); //
}
Символ & перед v1 указывает, что переменная v1 должна быть захвачена как ссылка. Захваченная по ссылке переменная действует так же, как любая другая ссылка. При использовании переменной в теле лямбда-выражения фактически применяется объект, с которым связана эта ссылка. В данном случае, когда лямбда-выражение возвращает v1, возвращается значение объекта, на который ссылается переменная v1.
Захват ссылок имеет те же проблемы и ограничения, что и возвращение ссылок (см. раздел 6.1.1). При захвате переменной по ссылке следует быть
Иногда захват по ссылке необходим. Например, может понадобиться, чтобы функция biggies() получала ссылку на поток ostream для записи символа, используемого как разделитель:
void biggies(vector
vector
ostream &os = cout, char c = ' ') {
//
//
for_each(words.begin(), words.end(),
[&os, c](const string &s) { os << s << c; });
}
Объекты потока ostream нельзя копировать (см. раздел 8.1.1); единственный способ захвата объекта os — это ссылка (или указатель).
При передаче лямбда-выражения функции, как и в случае вызова функции for_each(), лямбда-выражение выполняется немедленно. Захват объекта os по ссылке хорош потому, что переменные в функции biggies() существуют во время выполнения функции for_each().