在c++primer第五版p393中写道。
lambda捕获的变量是局部变量。
然后,书中显示了一个 ostream
作为一个被引用的参数,通过lambda的引用来获取,这是很相似的。
#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
的范围,但它可以被lambda捕获,而 "lambda捕获的变量是局部变量"。还有,为什么lambda不能被捕获?return os;
? 毕竟,不是 os
λ外的对象,并且 foo
的范围?
我感到困惑的是,这里
os
不是本地变量的foo
它存在于foo
的范围。
不,这是本地的,它确实 不 在外 foo
.
该 对象 所指 os
以外 foo
因为 os
是一种参考。但这与此无关,因为我们在讨论的是 变量,不 对象.
还有,为什么lambda不能
return os;
?
可以,你只需要指定一个显式的返回类型,否则返回类型将被推断为 std::ostream
即代码将试图以 拷贝 的流,而且是不可复制的。
但下面的方法可以用。
auto f = [&os]() -> std::ostream& { return os << "Hellow World !" << endl; };
上面的lambda被编译器编译成类似于... f2 在 foo2(). 所以lambda实例是在本地的 foo2 而 ostream 引用(指针)是本地 lambda 实例中的一个成员变量。
所以你必须确保,封装了 ostream 引用的 lambda 不会超过 ostream (os) 本身,在这种情况下不会发生,因为 lambda 实例只在函数作用域 -> 小于传递的 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;
}