我在玩bind,我在想,lambda 和函数指针一样昂贵吗?
我的意思是,据我了解 lambda,它们是仿函数的语法糖,并且绑定(bind)是相似的。但是,如果您这样做:
#include<functional>
#include<iostream>
void fn2(int a, int b)
{
std::cout << a << ", " << b << std::endl;
}
void fn1(int a, int b)
{
//auto bound = std::bind(fn2, a, b);
//static auto bound = std::bind(fn2, a, b);
//auto bound = [&]{ fn2(a, b); };
static auto bound = [&]{ fn2(a, b); };
bound();
}
int main()
{
fn1(3, 4);
fn1(1, 2);
return 0;
}
现在,如果我使用第一个 autobound = std::bind(fn2, a, b);
,我会得到输出
3, 4,第二个我得到1, 2
3, 4。第三次和第四次我得到的输出与第一次类似。3, 4
现在我明白为什么第一个和第二个以这种方式工作,它们在函数调用开始时被初始化(静态函数,仅在第一次被调用时)。然而,3 和 4 似乎具有编译器魔力,其中生成的仿函数并没有真正创建对封闭范围变量的引用,而是实际上锁定了符号,无论它是否仅在第一次或每次都初始化。
有人可以澄清这里到底发生了什么吗?
编辑:我缺少的是使用static autobound = std::bind(fn2, std::ref(a), std::ref(b));
使其作为第四个选项。
最佳答案
您有以下代码:
static auto bound = [&]{ fn2(a, b); };
仅在第一次调用此函数时才完成分配,因为它是静态
。所以实际上它只被调用一次。当您创建 lambda 时,编译器会创建闭包,因此会捕获第一次调用 fn1 时对 a 和 b 的引用。这是非常危险的。它可能会导致悬空引用。我很惊讶它没有崩溃,因为您正在从按值传递的函数参数到局部变量进行闭包。
我推荐这篇关于 lambda 的优秀文章:http://www.cprogramming.com/c++11/c++11-lambda-closures.html .
关于c++11 - 使用 std::bind 与 lambda 进行绑定(bind)。它们有多贵?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19264925/