C ++ 11 std :: bind和boost :: bind之间的区别


67

两者之间有什么区别吗?还是我可以安全地替换代码中所有出现的boost::bindby std::bind,从而消除对Boost的依赖?


我相信它们与C ++ 11发行时一样,与其他很多东西一样,std::bind已经被大量复制boost::bind
克里斯,2012年

10
问题是关于“相当多”的部分。通过Boost中取消的一些操作,进行了一些小的更改。
2012年

Answers:


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

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

  • boost::bind提供了一种直接的机制,可以防止对嵌套绑定表达式(boost::protect)进行热切评估,std::bind而不能。(也就是说,可以使用boost::protectstd::bind如果他们愿意,或平凡重新实现它自己。)

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


24

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

  • boost::bind似乎在某些情况下处理重载的函数名,而std::bind不会以相同的方式处理它们。参见 C ++ 11常见问题解答

(使用gcc 4.7.2,提升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,提升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,则构建也可能会中断。


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


2
INVOKE标准中的功能可与任何支持的智能指针配合使用operator*
Jonathan Wakely 2015年

8

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

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

我将命名空间命名为stdph

namespace stdph=std::placeholders;

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


在移植使用占位符的现有boost :: bind代码时,添加“使用命名空间std :: placeholders;”。文件顶部的占位符放入全局名称空间。非常便利。
goertzenator

1
问题是,在移植时,您通常最终仍会通过boost bind对其进行争执;通过某种方式,您最终会使用standard和boost占位符。
111111 2013年

这取决于我猜的项目。我从sed的一个体面大小的项目中机械删除了我所有的boost函数.hpp和bind.hpp包括,并且上面的命名空间指令很好地解决了。如果您在某些无法更改的标头中具有boost绑定,那么我会发现事情变得很丑陋。
goertzenator

2
@goertzenator:我认为问题更多是与其他任何Boost库的使用有关,因为我会下注至少三分之一的Boostboost::bind直接或间接使用。
ildjarn 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.