70

两者有什么区别吗?或者我是否可以安全地替换代码中出现的每一个boost::bindbystd::bind从而消除对 Boost 的依赖?

4

4 回答 4

90
  • boost::bind 重载了关系运算符std::bind没有。

  • boost::bind 支持非默认调用约定std::bind不保证(标准库实现可以将其作为扩展提供)。

  • boost::bind提供了一种直接机制,允许防止对嵌套绑定表达式 ( boost::protect) 的急切求值,std::bind但没有。(也就是说,如果他们愿意,可以使用boost::protectwith std::bind,或者自己简单地重新实现它。)

  • std::bind提供了一种直接机制,允许将任何用户定义的仿函数视为嵌套绑定表达式,以强制进行急切求值(std::is_bind_expression: [func.bind.isbind]/1, [func.bind.bind]/10),boost::bind但没有。

于 2012-05-11T17:13:33.333 回答
26

除了其他答案中引用的几个差异之外,还有另外两个差异:

  • boost::bind在某些情况下似乎处理重载的函数名称,而std::bind没有以相同的方式处理它们。见 c++11 常见问题

(使用 gcc 4.7.2,boost lib 版本 1_54)

void foo(){}
void foo(int i){}

auto badstd1 = std::bind(foo);  
//compile error: no matching function for call to bind(<unresolved overloaded function type>)
auto badstd2 = std::bind(foo, 1); 
//compile error: no matching function for call to bind(<unresolved overloaded function type>)
auto std1 = std::bind(static_cast<void(*)()>(foo)); //compiles ok
auto std2 = std::bind(static_cast<void(*)(int)>(foo), 1); //compiles ok
auto boost1 = boost::bind(foo, 1); //compiles ok
auto boost2 = boost::bind(foo); //compiles ok

因此,如果您只是将所有内容替换boost::bindstd::bind,您的构建可能会中断。

  • std::bind可以无缝绑定到 c++11 lambda 类型,而boost::bind从 boost 1.54 开始,似乎需要用户输入(除非定义了 return_type)。请参阅提升文档

(使用 gcc 4.7.2,boost lib 版本 1_54)

auto fun = [](int i) { return i;};
auto stdbound = std::bind(fun, std::placeholders::_1);
stdbound(1);

auto boostboundNaive = boost::bind(fun, _1);  //compile error.
// error: no type named ‘result_type’ ...
auto boostbound1 = boost::bind<int>(fun, _1); //ok
boostbound1(1);
auto boostbound2 = boost::bind(boost::type<int>(), fun, _1); //ok
boostbound2(1);

因此,如果您只是将所有内容替换std::bindboost::bind,您的构建也可能会中断。

于 2013-08-07T00:36:25.143 回答
16

除了上面列出的之外,boost::bind 还有一个重要的扩展点:get_pointer() 函数,它允许将 boost::bind 与任何智能指针集成,例如。ATL::CComPtr 等 http://www.boost.org/doc/libs/1_49_0/libs/bind/mem_fn.html#get_pointer

因此,使用 boost::bind 你也可以绑定一个weak_ptr: http: //lists.boost.org/Archives/boost/2012/01/189529.php

于 2012-05-13T09:54:31.700 回答
8

我没有完整的答案,但std::bind会使用可变参数模板而不是参数列表。

占位符在std::placeholdersas instd::placeholders::_1而不是全局命名空间中。

我将命名空间别名为 stdph

namespace stdph=std::placeholders;

除此之外,我更新到 C++11 没有问题

于 2012-05-11T16:58:38.247 回答