C++ 为什么在C+中的lambdas上使用'std::bind_front'+;20?

C++ 为什么在C+中的lambdas上使用'std::bind_front'+;20?,c++,lambda,c++20,stdbind,bind-front,C++,Lambda,C++20,Stdbind,Bind Front,正如在一个措辞类似的问题()中提到的,答案是-没有理由(并且还提到了为什么使用lambdas会更好) 我的问题是——如果在C++14中不再有使用绑定的理由,那么为什么标准委员会认为有必要添加C++20 它现在比lambda有什么新的优势吗?bind\u front绑定前X个参数,但是如果可调用调用调用更多参数,它们会被附加到末尾。当您只绑定函数的前几个参数时,这使得bind\u front非常可读 一个明显的例子是为绑定到特定实例的成员函数创建一个可调用函数: type *instance =

正如在一个措辞类似的问题()中提到的,答案是-没有理由(并且还提到了为什么使用lambdas会更好)

我的问题是——如果在C++14中不再有使用绑定的理由,那么为什么标准委员会认为有必要添加C++20


它现在比lambda有什么新的优势吗?

bind\u front
绑定前X个参数,但是如果可调用调用调用更多参数,它们会被附加到末尾。当您只绑定函数的前几个参数时,这使得
bind\u front
非常可读

一个明显的例子是为绑定到特定实例的成员函数创建一个可调用函数:

type *instance = ...;

//lambda
auto func = [instance](auto &&... args) -> decltype(auto) {return instance->function(std::forward<decltype(args)>(args)...);}

//bind
auto func = std::bind_front(&type::function, instance);
type*实例=。。。;
//兰姆达
auto func=[instance](auto&&…args)->decltype(auto){return instance->function(std::forward(args)…);}
//束缚
auto func=std::bind_front(&type::function,instance);
bind_front
版本噪音小得多。它直截了当地指出了这一点,正好有3个命名的东西:
bind\u front
、要调用的成员函数和要调用它的实例。这就是我们的情况所需要的:一个标记,表示我们正在创建一个函数的第一个参数的绑定,要绑定的函数,以及要绑定的参数。没有多余的语法或其他细节

相比之下,lambda在这个位置有很多我们不关心的东西。
自动。。。args
bit,std::forward之类的东西。要弄清楚它在做什么有点困难,而且读起来肯定要长得多


请注意,
bind\u front
根本不允许使用
bind
的占位符,因此它不是真正的替代品。它更像是最有用的
bind

形式的缩写,提出它的论文有一些很好的引人注目的用例。我将在这里对它们进行总结,否则我将不得不引用论文的大部分内容,所以一定要去看看:

自动完全转发 使用lambda需要
std::forward
样板文件

传播变异性 在按值存储对象的情况下,
std::bind
std::bind\u front
propagate constness,但在捕获lambda的情况下,用户必须选择一个可变或常量版本,从而产生问题

保持返回类型 使用lambda需要用户端的
->decltype(auto)
样板文件

保值范畴 就像保持可变性一样,除了现在我们讨论的是左值/右值,只有
std::bind_front
正确地做到了这一点

支持一次性调用 传播可变性与保值范畴的一个结果

保留异常规范 这一点现在尤其重要,因为异常规范现在是类型系统的一部分


还有一些有用的注释:

此函数用于替换std::bind。与std::bind不同,它 不支持任意参数重新排列,并且没有特殊的 嵌套绑定表达式或std::reference_包装的处理方法。在…上 另一方面,它关注通话的价值类别 包装器对象并传播的异常规范 底层呼叫接线员


值得注意的是,
bind\u front
带来的优化器好处比
bind
更简单、更受限制。小得多的实现,应该很容易让优化器看穿。