为什么在C ++ 14中对lambda使用std :: bind? [英] Why use std::bind over lambdas in C++14?

查看:82
本文介绍了为什么在C ++ 14中对lambda使用std :: bind?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C ++ 11之前,我经常使用boost::bindboost::lambda. bind部分使它成为标准库(std::bind),另一部分成为核心语言(C ++ lambda)的一部分,并使lambda的使用变得更加容易.如今,我几乎不使用std::bind,因为我几乎可以使用C ++ lambda进行任何操作.我想到的是std::bind的一个有效用例:

Before C++11 I used boost::bind or boost::lambda a lot. The bind part made it into the standard library (std::bind) the other part became part of the core language (C++ lambdas) and made the use of lambdas a lot easier. Nowadays, I hardly use std::bind, since I can do almost anything with C++ lambdas. There's one valid use-case for std::bind that I can think of:

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的

The C++14 equivalent for that would be

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

更短,更简洁. (由于auto参数,在C ++ 11中这还行不通.)std::bind是否有任何其他有效的用例可以击败C ++ lambdas替代品,或者std::bind与C ++ 14无关?

Much shorter and more concise. (In C++11 this does not work yet because of the auto parameters.) Is there any other valid use case for std::bind beating the C++ lambdas alternative or is std::bind superfluous with C++14?

推荐答案

Scott Meyers给出了谈论.这就是我所记得的:

Scott Meyers gave a talk about this. This is what I remember:

在C ++ 14中,没有有用的绑定可以做的事,而lambdas也无法做到.

In C++14 there is nothing useful bind can do that can't also be done with lambdas.

在C ++ 11 中,但是lambda不能完成某些事情:

In C++11 however there are some things that can't be done with lambdas:

  1. 在创建lambda时,您无法在捕获时移动变量.变量始终被捕获为左值.对于绑定,您可以编写:

  1. You can't move the variables while capturing when creating the lambdas. Variables are always captured as lvalues. For bind you can write:

auto f1 = std::bind(f, 42, _1, std::move(v));

  • 无法捕获表达式,只能捕获标识符.对于绑定,您可以编写:

  • Expressions can't be captured, only identifiers can. For bind you can write:

    auto f1 = std::bind(f, 42, _1, a + b);
    

  • 重载函数对象的参数.问题中已经提到了这一点.

  • Overloading arguments for function objects. This was already mentioned in the question.

    在C ++ 14 中,所有这些可能.

    In C++14 all of these possible.

    1. 移动示例:

    1. Move example:

    auto f1 = [v = std::move(v)](auto arg) { f(42, arg, std::move(v)); };
    

  • 表达示例:

  • Expression example:

    auto f1 = [sum = a + b](auto arg) { f(42, arg, sum); };
    

  • 查看问题

  • See question

    完美转发:您可以编写

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

  • bind的一些缺点:

    Some disadvantages of bind:

    • 绑定是按名称绑定的,因此,如果您有多个具有相同名称的函数(重载的函数),绑定将不知道要使用哪个绑定.以下示例将不会编译,而lambda不会出现问题:

    • Bind binds by name and as a result if you have multiple functions with the same name (overloaded functions) bind doesn't know which one to use. The following example won't compile, while lambdas wouldn't have a problem with it:

    void f(int); void f(char); auto f1 = std::bind(f, _1, 42);
    

  • 使用绑定函数时不太可能内联
  • 另一方面,从理论上讲,lambda可能比绑定生成更多的模板代码.因为对于每个lambda,您都有一个唯一的类型.对于绑定,只有当您具有不同的参数类型和不同的函数时(我想实际上,但是使用相同的参数和函数绑定几次不会经常发生).

    On the other hand lambdas might theoretically generate more template code than bind. Since for each lambda you get a unique type. For bind it is only when you have different argument types and a different function (I guess that in practice however it doesn't happen very often that you bind several time with the same arguments and function).

    乔纳森·韦克利(Jonathan Wakely)在回答中提到的实际上是不使用绑定的另一个原因.我不明白为什么您会想默默地忽略参数.

    What Jonathan Wakely mentioned in his answer is actually one more reason not to use bind. I can't see why you would want to silently ignore arguments.

    这篇关于为什么在C ++ 14中对lambda使用std :: bind?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆