【问题标题】:When should I use std::bind?我应该什么时候使用 std::bind?
【发布时间】:2013-03-24 12:44:40
【问题描述】:

每次我需要使用 std::bind 时,我最终都会使用 lambda。那么什么时候应该使用std::bind?我刚刚从一个代码库中删除了它,我发现 lambdas 总是比std::bind 更简单、更清晰。 std::bind 不是完全没有必要吗?将来不应该弃用吗?我什么时候应该更喜欢 std::bind 而不是 lambda 函数? (它与 lambdas 同时进入标准肯定是有原因的。)

我还注意到越来越多的人熟悉 lambda(因此他们知道 lambda 的作用)。但是,熟悉std::bindstd::placeholders 的人却少得多。

【问题讨论】:

  • Bind Vs Lambda?的可能重复
  • 参见stackoverflow.com/a/17545183/1274850

标签: c++ c++11 lambda bind standard-library


【解决方案1】:

这是你不能用 lambda 做的事情:

std::unique_ptr<SomeType> ptr = ...;
return std::bind(&SomeType::Function, std::move(ptr), _1, _2);

Lambdas 不能捕获只能移动的类型;它们只能通过复制或左值引用来捕获值。虽然诚然,这是一个临时问题,正在为 C++14 积极解决;)

“更简单更清晰”是见仁见智的问题。对于简单的绑定情况,bind 可以减少输入。 bind 也只专注于函数绑定,所以如果你看到 std::bind,你就知道你在看什么。而如果您使用 lambda,则必须查看 lambda 实现以确定它的作用。

最后,C++ 不会仅仅因为其他一些特性可以做到这一点而弃用它。 auto_ptr 已被弃用,因为使用它本质上是危险的,并且有一个不危险的替代方案。

【讨论】:

  • +1。 Scott Meyers's upcoming book "Effective C++11" 中似乎有一个项目:“Prefer lambdas to std::bind”。我没有足够的洞察力对此发表评论,但如果可以的话,那就太好了。
  • 感谢您的精彩回答!有一篇关于移动捕获的文章:marcoarena.wordpress.com/2012/11/01/…希望我们能在下一个标准中获得真正的移动捕获。
  • C++-14 将修复 lambdas 的这一缺陷。
  • @AndyProwl 最适用的是您引用的书中的简短引用:“......从 C++14 开始,[std::bind] 没有好的用例”跨度>
  • 虽然我认为,使用 c++14,您可能可以用 lambdas 完全替换 std::bind (我大多这样做)我仍然喜欢你关于 std::bind 不那么强大的观点,因此说明意图更清楚。
【解决方案2】:

您可以使用 std::bind 创建多态对象,而使用 lambdas 则无法创建多态对象,即可以使用不同的参数类型调用 std::bind 返回的调用包装器:

#include <functional>
#include <string>
#include <iostream>

struct Polly
{
  template<typename T, typename U>
    auto operator()(T t, U u) const -> decltype(t + u)
    { return t + u; }
};

int main()
{
  auto polly = std::bind(Polly(), std::placeholders::_1, "confusing");

  std::cout << polly(4) << polly(std::string(" this is ")) << std::endl;    
}

我将其创建为 puzzle 不是一个好的代码示例,但它确实演示了多态调用包装器。

【讨论】:

  • 是的,在 C++14 中这相当于绑定表达式:[p = Polly{}](auto t) { return p(t, "confusing"); }
  • @Elliot Pollyoperator() 显然是 const,所以我不明白你的意思。问题中的代码编译得很好,我上面第一条评论中的 lambda 表达式也是如此。
  • 道歉。我愚蠢地错过了const。 '在评论之前应该仔细看看。
猜你喜欢
  • 1970-01-01
  • 2011-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-12
  • 1970-01-01
相关资源
最近更新 更多