gpt4 book ai didi

c++ - 为什么在 C++14 中使用 std::bind 而不是 lambda?

转载 作者:IT老高 更新时间:2023-10-28 13:24:14 26 4
gpt4 key购买 nike

在 C++11 之前,我经常使用 boost::bindboost::lambdabind 部分进入标准库(std::bind),另一部分成为核心语言的一部分(C++ lambdas)并大量使用 lambdas更轻松。现在,我几乎不使用 std::bind,因为我几乎可以用 C++ lambda 做任何事情。我能想到 std::bind 的一个有效用例:

struct foo
{
template < typename A, typename B >
void operator()(A a, B b)
{
cout << a << ' ' << b;
}
};

auto f = bind(foo(), _1, _2);
f( "test", 1.2f ); // will print "test 1.2"

对应的 C++14 是

auto f = []( auto a, auto b ){ cout << a << ' ' << b; }
f( "test", 1.2f ); // will print "test 1.2"

更短更简洁。 (在 C++11 中,由于 auto 参数,这还不起作用。) std::bind 是否有任何其他有效用例击败 C++ lambdas 替代方案或者 std::用C++14绑定(bind)多余?

最佳答案

Scott Meyers 给出了 talk对这个。这是我记得的:

在 C++14 中,没有什么有用的绑定(bind)可以做,而 lambdas 也不能做。

在 C++11 中,有些事情不能用 lambdas 完成:

  1. 在创建 lambda 时,您不能在捕获时移动变量。变量总是被捕获为左值。对于绑定(bind),您可以编写:

    auto f1 = std::bind(f, 42, _1, std::move(v));
  2. 无法捕获表达式,只有标识符可以。对于绑定(bind),您可以编写:

    auto f1 = std::bind(f, 42, _1, a + b);
  3. 函数对象的重载参数。这已经在问题中提到了。

  4. 不可能完美地提出论点

在 C++14 中,所有这些都是可能的。

  1. 移动示例:

    auto f1 = [v = std::move(v)](auto arg) { f(42, arg, std::move(v)); };
  2. 表达式示例:

    auto f1 = [sum = a + b](auto arg) { f(42, arg, sum); };
  3. 查看问题

  4. 完美转发:可以写

    auto f1 = [=](auto&& arg) { f(42, std::forward<decltype(arg)>(arg)); };

bind的一些缺点:

  • Bind 按名称绑定(bind),因此如果您有多个具有相同名称的函数(重载函数),则 bind 不知道使用哪一个。以下示例无法编译,而 lambdas 不会有问题:

    void f(int); void f(char); auto f1 = std::bind(f, _1, 42);
  • 使用绑定(bind)函数时不太可能被内联

另一方面,从理论上讲,lambda 可能会生成比绑定(bind)更多的模板代码。因为对于每个 lambda,你都会得到一个唯一的类型。对于绑定(bind),只有当你有不同的参数类型和不同的函数时(我猜在实践中,你用相同的参数和函数绑定(bind)多次并不会经常发生)。

Jonathan Wakely 在他的回答中提到的实际上是不使用绑定(bind)的另一个原因。我不明白你为什么要默默地忽略参数。

关于c++ - 为什么在 C++14 中使用 std::bind 而不是 lambda?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17363003/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com