简体   繁体   中英

Difference between boost::thread and std::thread

I have a place where things work using boost::thread(example using 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);
  }

If I try to use it with std:thread I get compile error:

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));
}

In theory, both should work, since std::thread has a vararg constructor which basically invokes its arguments as if it were used with std::bind . The problem appears to be that, at least in my implementation (gcc 4.6.3), neither std::thread nor std::bind can determine which overload of run was intended, resulting in a compilation error.

However, if you use boost::bind , this works. So I would use, and manually perform the bind manually:

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));
}

Edit: It appears that boost::bind succeeds because it's got a ton of overloads, and based on the number of arguments it was provided, during overload resolution and template substitution of boost::bind it can determine which overload of boost::asio::io_service::run was intended.

However, since std::bind and std::thread rely on a vararg tempalte arguments, both overloads of run are equally valid, and the compiler cannot resolve which one to use. This ambiguity results in a failure to determine which results in the failures you are seeing.

So another solution is:

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));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM