c++11 - 使用 std::bind 与 lambda 进行绑定(bind)。它们有多贵?

标签 c++11 lambda stdbind

我在玩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/

相关文章:

c++ - 应该在策略模式中使用安全指针吗?

python - 使用 Zappa 配置 AWS Lambda 函数,出现未知错误

java - 在Java中,我可以做一个谓词,将一个过滤器应用于多个对象吗?

Python 2 列表理解和评估

c++ - 将一个对象的函数传递给另一个类的另一个 std::function

c++ - 使用 std::bind 从 BinaryPredicate 创建 UnaryPredicate 以在 std::transform 中使用

c++ - 高效频率计数器

c++ - 变量模板和 std::cout -- 构造顺序

抽象类中的c++克隆函数