这个对 ostream 的引用是一个本地变量吗?

问题描述 投票:0回答:1

在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的范围?

c++ lambda local-variables reference-parameters
1个回答
3
投票

我感到困惑的是,这里 os 不是本地变量的 foo它存在于 foo的范围。

不,这是本地的,它确实 在外 foo.

对象 所指 os 以外 foo因为 os 是一种参考。但这与此无关,因为我们在讨论的是 变量,不 对象.

还有,为什么lambda不能 return os;?

可以,你只需要指定一个显式的返回类型,否则返回类型将被推断为 std::ostream即代码将试图以 拷贝 的流,而且是不可复制的。

但下面的方法可以用。

auto f = [&os]() -> std::ostream& { return os << "Hellow World !" << endl; };

3
投票

上面的lambda被编译器编译成类似于... f2foo2(). 所以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;
}
© www.soinside.com 2019 - 2024. All rights reserved.