Инкапсулируйте функцию потока с помощью привязки boost

В настоящее время я создаю boost::threads следующим образом:

  boost::thread m_myThread; //member variable
  //...
  m_myThread = boost::thread(boost::bind(&MyClass::myThreadFunction, this));

Это запустит поток, который выполняет функцию-член «myThreadFunction».

Я хотел бы инкапсулировать начало нового потока и использовать что-то вроде

boost::thread m_myThread; //member variable
//...
startAThread(&m_myThread, boost::bind(&MyClass::myThreadFunction, this), 123 /*some int argument*/);

Я думал, что смогу реализовать startAThread следующим образом:

namespace internal
{
    template <typename Callable>
    void threadhelper(Callable func, int x)
    {
        doSomething(x);
        func();
    }
}
template <typename Callable>
void startAThread(boost::thread* threadToCreate, Callable func, int x)
{

    *threadToCreate = boost::thread(boost::bind(internal::threadhelper<Callable>, func, x));
}

Однако это не скомпилируется с

usr/include/boost/bind/bind.hpp: In member function 'void boost::_bi::list2<A1, A2>::operator()(boost::_bi::type<void>, F&, A&, int) [with F = void (*)(boost::_bi::bind_t<void, boost::_mfi::mf0<void, MyClass>, boost::_bi::list1<boost::_bi::value<MyClass*> > >, int), A = boost::_bi::list0, A1 = boost::_bi::bind_t<void, boost::_mfi::mf0<void, MyClass>, boost::_bi::list1<boost::_bi::value<MyClass*> > >, A2 = boost::_bi::value<int>]':
usr/include/boost/bind/bind_template.hpp:20:   instantiated from 'typename boost::_bi::result_traits<R, F>::type boost::_bi::bind_t<R, F, L>::operator()() [with R = void, F = void (*)(boost::_bi::bind_t<void, boost::_mfi::mf0<void, MyClass>, boost::_bi::list1<boost::_bi::value<MyClass*> > >, int), L = boost::_bi::list2<boost::_bi::bind_t<void, boost::_mfi::mf0<void, MyClass>, boost::_bi::list1<boost::_bi::value<MyClass*> > >, boost::_bi::value<int> >]'
usr/include/boost/thread/detail/thread.hpp:61:   instantiated from 'void boost::detail::thread_data<F>::run() [with F = boost::_bi::bind_t<void, void (*)(boost::_bi::bind_t<void, boost::_mfi::mf0<void, MyClass>, boost::_bi::list1<boost::_bi::value<MyClass*> > >, int), boost::_bi::list2<boost::_bi::bind_t<void, boost::_mfi::mf0<void, MyClass>, boost::_bi::list1<boost::_bi::value<MyClass*> > >, boost::_bi::value<int> > >]'
MyClass.cpp:160:   instantiated from here
usr/include/boost/bind/bind.hpp:313: error: conversion from 'void' to non-scalar type 'boost::_bi::bind_t<void, boost::_mfi::mf0<void, MyClass>, boost::_bi::list1<boost::_bi::value<MyClass*> > >' requested

Что означает эта ошибка? Что не так с кодом?

Большое спасибо!


person Philipp    schedule 14.10.2011    source источник
comment
Вы также должны добавить вызов createThreadWithPriority (или это вызов startAThread выше?) -- Простая вещь, которая неверна, заключается в том, что вы не передаете func вниз от createThreadWithPriority к internal::threadhelper.   -  person David Rodríguez - dribeas    schedule 14.10.2011
comment
конечно, ты прав. Это были две ошибки, допущенные при подготовке кода к публикации. Теперь он должен соответствовать коду, который у меня есть на самом деле.   -  person Philipp    schedule 14.10.2011
comment
Если вы спрашиваете о проблеме с компилятором, вы всегда должны публиковать код, который повторяет проблему, и пытаться помочь другим в чтении сообщений об ошибках, насколько это возможно. В частности, в коде нет указаний на то, где находится строка 160 MyClass.cpp. (Я предполагаю, что перед теми, на которые вы указываете, ошибок нет). Я не знаю, можно ли легко ответить даже с этой информацией, поэтому я бы попытался создать тест, максимально похожий на ваш код, и заставить его провалиться таким же образом (начните с удаления boost::thread из уравнения).   -  person David Rodríguez - dribeas    schedule 14.10.2011


Ответы (1)


Пытаться

namespace internal
{
    template <typename Callable>
    void threadhelper(Callable func, int x)
    {
        doSomething(x);
        func();
    }
}
template <typename Callable>
void startAThread(boost::thread& threadToCreate, Callable func, int x) {        
    threadToCreate = boost::thread(boost::bind(&internal::threadhelper<Callable>, func, x));
}

Я также использовал ссылку вместо указателя.

person Pawel Zubrycki    schedule 07.11.2011