为什么在C++20中对lambdas使用"std::bind_front"
Why use `std::bind_front` over lambdas in C++20?
正如在一个措辞类似的问题中提到的(为什么在c++14中对lambdas使用绑定?(答案是-没有理由(还提到为什么使用lambdas更好(。
我的问题是,如果在C++14中不再有使用绑定的理由,为什么标准委员会认为有必要在C++20中添加std::bind_front
?
它现在比lambda有什么新的优势吗?
bind_front
绑定前X个参数,但如果可调用调用调用更多参数,它们就会被附加到末尾。当您只绑定函数的前几个参数时,这使得bind_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);
bind_front
版本噪音较小。它切中要害,正好有三个命名的东西:bind_front
,要调用的成员函数,以及将在其上调用它的实例。这就是我们的情况所需要的:一个标记,表示我们正在创建函数的第一个参数、要绑定的函数和要绑定的参数的绑定。没有多余的语法或其他细节。
相比之下,lambda在这个位置有很多我们不关心的东西。auto... args
位、std::forward
位等等。弄清楚它在做什么有点困难,而且阅读时间肯定要长得多。
注意,bind_front
根本不允许使用bind
的占位符,所以它并不是真正的替代品。它更像是bind
最有用形式的简写。
提出它的论文简化了部分函数应用程序,有一些很好的令人信服的用例。我将在这里总结它们,因为否则我将不得不引用大部分论文,所以一定要去看看:
自动完美转发
使用lambda将涉及std::forward
样板
传播可变性
在按值std::bind
和std::bind_front
存储对象的情况下传播常量,但在捕获lambda的情况下,用户必须选择一个可变或常量版本,这会产生问题
保留返回类型
使用lambda将涉及用户端的-> decltype(auto)
样板。
保值类别
就像保持可变性一样,只是现在我们谈论的是左值/右值,只有std::bind_front
能正确地实现
支持一次性调用
传播可变性和保值类别的结果
保留异常规范
这一点现在尤其重要,因为异常规范现在是类型系统的一部分
cppreference也有一些有用的注释:
此函数旨在取代std::bind。与std::bind不同,它不支持任意参数重排,并且没有特殊功能嵌套绑定表达式或std::reference_wrappers的处理。在…上另一方面,它关注呼叫的价值类别包装器对象,并传播的异常规范底层呼叫运营商。
- POCO::PostgreSQL:如何将std::vector支持添加到`Binder::bind`
- boost::bind()类似的东西,但用于函数调用
- 使用 std::应用于 std::bind
- PCL:当我在setConditionFunction中使用std::bind 时,没有合适的转换函数
- std::bind on statd::array 的运算符 []
- std::bind c++ in if statement
- std::bind 是否实现了 std::ref 和 std::cref 来消除函数调用的歧义?
- C++ 事件管理器的回调,使用 std::function 和 std:bind 以及派生类作为参数
- 试图克服 std::bind 编译错误
- c++ std::bind within function
- std::bind to void* to std::function
- std::bind,无法让具有单个参数的方法工作
- std::bind 和 std::函数术语不值为接受 0 个参数?
- 在调用 std::bind 的产品后意外调用析构函数
- 使用 object 中的方法调用带有 std::bind 和 std::function.target 的 C 样式函数
- 我们应该在使用 std::bind 应用之前检查一个不为空的函数吗?
- 为什么 std::bind 静态类型检查传递给函数的参数?
- 对函数库中的语法感到困惑 std::bind
- 在模板类成员上使用 std::bind
- 泛化传递给 boost::bind 的参数