У меня есть место, где все работает, используя 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));
}
По идее оба должны работать, так как std::thread
имеет конструктор vararg, который в основном вызывает свои аргументы, как если бы он был использован с std::bind
, Проблема заключается в том, что, по крайней мере, в моей реализации (gcc 4.6.3), ни std::thread
ни std::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::bind
а также std::thread
полагаться на аргументы vararg tempalte, обе перегрузки 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));
}
Других решений пока нет …