Это ссылка на локальную переменную
В C++primer 5th edition p393 написано:
Переменные, захваченные лямбдой, являются локальными переменными
Затем книга показывает ostream
в качестве параметра, на который указывает ссылка, который фиксируется лямбда-функцией по ссылке. Это похоже:
#include <iostream>
using namespace std;
void foo(ostream &os) {
auto f = [&os]() { os << "Hellow World !" << endl; //return os;
};
f();
}
void main() {
foo(cout);
system("pause");
}
Я борюсь с тем, что здесь os не является локальной переменной для foo
, он существует вне foo
область видимости, но это может быть захвачено лямбдой, в то время как "переменные, захваченные лямбдой, являются локальными переменными". Что мне здесь не хватает? Кроме того, почему лямбда не можетreturn os;
? В конце концов, неos
объект, который существует вне лямбда и foo
объем?
2 ответа
Я борюсь с тем, что здесь
os
не является локальной переменной дляfoo
, он существует внеfoo
объем,
Нет, это локальное, оно не существует внеfoo
.
Объект, который ссылаетсяos
существует вне foo
, потому как os
это ссылка. Но здесь это не имеет значения, поскольку мы говорим о переменных, а не об объектах.
Кроме того, почему лямбда не может
return os;
?
Может, вам просто нужно указать явный тип возвращаемого значения, в противном случае тип возвращаемого значения определяется как std::ostream
, т.е. код будет пытаться скопировать поток, и его нельзя копировать.
Но работает следующее:
auto f = [&os]() -> std::ostream& { return os << "Hellow World !" << endl; };
Лямбда сверху компилируется компилятором во что-то похожее на f2 в foo2 (). Таким образом, экземпляр лямбда является локальным внутри foo2, а ссылка (указатель) ostream - это член, изменяемый в локальном экземпляре лямбда.
Таким образом, вы должны убедиться, что лямбда с обернутой ссылкой на ostream не переживает сам ostream (os), чего не происходит в этом случае, потому что экземпляр лямбда живет только в пределах функции -> меньше, чем объем переданного ostream ссылка os аргумент.
#include <iostream>
using namespace std;
void foo(ostream &os) {
auto f = [&os]() { os << "Hellow World !" << endl; //return os;
};
f();
}
void foo2(ostream& os) {
// The lambda f from foo is compiled to something similar to f2.
struct f2 {
f2(ostream& oss)
: os_(oss) {}
void operator()() const
{
os_ << "Hellow World !" << endl;
}
private:
ostream& os_; // Note: this is reference, but local to f2 ( == "lambda")
};
f2 t(os);
t(); // call "lambda"
}
int main() {
foo(cout);
foo2(cout);
return 0;
}