【问题标题】:Difference between boost::thread and std::threadboost::thread 和 std::thread 之间的区别
【发布时间】:2012-11-20 15:14:39
【问题描述】:

我有一个使用 boost::thread 的地方(使用 boost::asio 的示例)

  std::vector<boost::shared_ptr<boost::thread> > threads;
  for (std::size_t i = 0; i < io_services_.size(); ++i)
  {
    boost::shared_ptr<boost::thread> thread(new boost::thread(
          boost::bind(&boost::asio::io_service::run, io_services_[i])));
    threads.push_back(thread);
  }

如果我尝试将它与 std:thread 一起使用,则会出现编译错误:

std::vector<std::thread> threads;
for (std::size_t i = 0; i < this->ioServices.size(); ++i)
{
    std::thread thread(&boost::asio::io_service::run, ioServices[i]); // compile error std::thread::thread : no overloaded function takes 2 arguments   

    threads.push_back(std::move(thread));
}

【问题讨论】:

  • 您的编译错误不包含对boost::bind的调用?
  • @BartekBanachewicz 更新了标题,因为这与 boost::tread 和 std::thread 之间的区别有关
  • @Chad tnx 指出了这一点。更新
  • 我仍然没有看到更新。您正在调用 std::thread 构造函数,并带有两个它不期望的参数。如果您使用这两个参数构造了一个 boost::bind 对象,我希望它能够编译并工作。

标签: c++ boost c++11


【解决方案1】:

理论上,两者都应该工作,因为std::thread 有一个可变参数构造函数,它基本上调用它的参数,就好像它与std::bind 一起使用一样。问题似乎是,至少在我的实现(gcc 4.6.3)中,std::threadstd::bind 都无法确定 run 的哪个重载,从而导致编译错误。

但是,如果您使用 boost::bind,则可以。所以我会使用并手动执行绑定:

std::vector<std::thread> threads;
for (std::size_t i = 0; i < this->ioServices.size(); ++i)
{
    std::thread thread(boost::bind(&boost::asio::io_service::run, ioServices[i])); 

    threads.push_back(std::move(thread));
}

编辑:boost::bind 似乎成功了,因为它有大量的重载,并且根据它提供的参数数量,在重载解析和 boost::bind 的模板替换期间,它可以确定 boost::asio::io_service::run 的哪个重载是有意的。

但是,由于std::bindstd::thread 依赖于可变参数模板参数,run 的两个重载同样有效,编译器无法解析使用哪一个。这种模棱两可导致无法确定您所看到的失败的结果。

所以另一种解决方案是:

std::vector<std::thread> threads;
typedef std::size_t (boost::asio::io_service::*signature_type)();
signature_type run_ptr = &boost::asio::io_service::run;

for (std::size_t i = 0; i < this->ioServices.size(); ++i)
{
    std::thread thread(run_ptr, ioServices[i]); 

    threads.push_back(std::move(thread));
}

【讨论】:

  • 我觉得有趣的是 io_service::run 不是一个静态方法,不知道 boot::bind 如何绑定到那个...
  • 建议的第一个解决方案也有效。至少它在 vs2012 下编译
  • @Gmt: boost::bind(和std::bind)通过假设提供的第一个参数(在绑定时或调用时)是引用或指向成员函数的指针来工作适当的类型,然后将其用作调用成员函数的对象。
  • @DaveS 错过了“调用时间”的部分。我认为如果成员必须做 std::bind(&instance_member, objInstance, member_args..)
猜你喜欢
  • 2012-01-22
  • 2015-01-28
  • 1970-01-01
  • 2020-12-21
  • 1970-01-01
  • 2012-07-30
  • 2020-12-15
  • 2014-09-02
  • 1970-01-01
相关资源
最近更新 更多