【问题标题】:Why `boost::bind()` can't be replaced with `std::bind()` here? [duplicate]为什么 `boost::bind()` 在这里不能用 `std::bind()` 代替? [复制]
【发布时间】:2013-11-23 03:52:11
【问题描述】:

这部分代码来自example

int main()
{
  boost::asio::io_service io;
  printer p(io);
  boost::thread t(boost::bind(&boost::asio::io_service::run, &io));
  io.run();
  t.join();

  return 0;
}

如果我将boost::bind(&boost::asio::io_service::run, &io) 替换为std::bind(&boost::asio::io_service::run, &io),则会出现编译错误:

.../usr/lib/c++/v1/functional:1843:1: note: candidate template
  ignored: couldn't infer template argument '_Fp'
bind(_Fp&& __f, _BoundArgs&&... __bound_args)
^
/usr/lib/c++/v1/functional:1852:1: note: candidate template
  ignored: couldn't infer template argument '_Rp'
bind(_Fp&& __f, _BoundArgs&&... __bound_args)
^
1 error generated.

为什么会出现这个错误?

为什么std::bind(&printer::print1, &p) 有效,而std::bind(&boost::asio::io_service::run, &io) 无效?

【问题讨论】:

  • 添加错误信息的所有行。
  • boost::thread 有一个转发构造函数,所以你根本不需要绑定:boost::thread t(&boost::asio::io_service::run, &io);

标签: c++ boost c++11 bind boost-asio


【解决方案1】:

编译器告诉您它无法确定std::bind 的第一个参数的类型。

如果您查看io_service::run,您会发现它已超载。编译器有一个选择,这可能是编译器无法确定类型的原因。要对此进行测试,您可以使用演员表:

std::bind(static_cast<size_t (boost::asio::io_service::*)()>(&boost::asio::io_service::run), &io)

这种方式使选择在代码中明确。

使用现代编译器,您根本不需要使用 bind。你可以这样做:

[&]() { io.run(); }

这避免了std::bind 模板的所有问题。您需要考虑变量生命周期和副本与引用。

【讨论】:

  • 谢谢,但它也不能转换为std::function&lt;size_t ()&gt;,但是当我将它转换为std::size_t (boost::asio::io_service::*)()时它可以工作,boost::bind可以处理重载函数,也许lambda函数是更多帮助!
  • std::function&lt;size_t ()&gt; 没有接受指向成员函数的指针的构造函数(更不用说在这里创建 std::function 绝对是不必要的开销)。
  • @IgorR。是的,你是对的。我在文本中写了“演员”,但随后完全输入了其他内容!将修复代码。
  • @user2763477 正如 IgorR 所指出的,我的代码与我的文本不匹配。更新;打字太快了!
猜你喜欢
  • 2012-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-20
相关资源
最近更新 更多