2013-09-18 2 views
2

Я хотел бы создать активные объекты, которые запускают новый поток (выполняющий оператор своих функций), когда они создаются.Активные объекты - создание потока из класса объектов-функций

template <typename R, typename... Ts> // VARIADIC TEMPLATE 
class active_object{ 
protected: 
std::thread* t; 
    R& result; 

public: 
    active_object(R init, Ts... args) : t{nullptr}, result{init} { 
    start_thread(args...); 
    } 

    void start_thread(Ts... args){ 
    t = new std::thread(*this, args...); 
    } 

    ~active_object(){ 
    if(t->joinable()) 
     t->join(); 
    delete t; 
    } 

    void set_result(R& result_){ 
    result = result_; 
    } 

    // pure virtual function => makes this class abstract 
    virtual void operator()(Ts... args) = 0; 

}; 

Тогда:

class myactiveobject : public active_object<double,int,int,bool> { 
public: 
    myactiveobject(double init, int i1, int i2, bool b) : active_object{init, i1, i2, b} {} 

    void operator()(int x, int y, bool which){ 
     double result = 0.1; 
     if(which) 
      result *= x; 
     else 
      result *= y; 

     set_result(result); 
    } 
}; 

Теперь, я получаю эту ошибку:

$ g++ -std=c++11 -pthread main.cpp 
In file included from /usr/include/c++/4.7/functional:56:0, 
       from /usr/include/c++/4.7/thread:39, 
       from multithreading.h:2, 
       from main.cpp:1: 
/usr/include/c++/4.7/tuple: In instantiation of ‘struct std::_Head_base<0u, roby::multithreading::active_object<double, int, int, bool>, false>’: 
/usr/include/c++/4.7/tuple:215:12: required from ‘struct std::_Tuple_impl<0u, roby::multithreading::active_object<double, int, int, bool>, int, int, bool>’ 
/usr/include/c++/4.7/tuple:374:11: required from ‘class std::tuple<roby::multithreading::active_object<double, int, int, bool>, int, int, bool>’ 
/usr/include/c++/4.7/functional:1601:39: required from ‘struct std::_Bind_simple<roby::multithreading::active_object<double, int, int, bool>(int, int, bool)>’ 
/usr/include/c++/4.7/thread:133:9: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = roby::multithreading::active_object<double, int, int, bool>&; _Args = {int&, int&, bool&}]’ 
multithreading.h:36:5: required from ‘void roby::multithreading::active_object<R, Ts>::start_thread(Ts ...) [with R = double; Ts = {int, int, bool}]’ 
multithreading.h:31:5: required from ‘roby::multithreading::active_object<R, Ts>::active_object(R, Ts ...) [with R = double; Ts = {int, int, bool}]’ 
main.cpp:11:85: required from here 
/usr/include/c++/4.7/tuple:166:13: error: cannot declare field ‘std::_Head_base<0u, roby::multithreading::active_object<double, int, int, bool>, false>::_M_head_impl’ to be of abstract type ‘roby::multithreading::active_object<double, int, int, bool>’ 
In file included from main.cpp:1:0: 
multithreading.h:23:9: note: because the following virtual functions are pure within ‘roby::multithreading::active_object<double, int, int, bool>’: 
multithreading.h:51:17: note: void roby::multithreading::active_object<R, Ts>::operator()(Ts ...) [with R = double; Ts = {int, int, bool}] 

В то время как в случае, когда я делаю оператор() на active_object не-чистой виртуальной функции, он компилируется, но дает мне ошибку сегментации в std :: thread().

+5

Почему 'новый std :: thread', а не только' std :: thread'? - С уважением, Бесконечная динамическая полиция. –

+1

Кроме того, вы сохраняете ссылку на результат, а не копию. Хотя это не объясняет ошибку времени компиляции. –

+1

Вы, кажется, много работаете над реализацией худшей версии 'std :: async'. – zch

ответ

3

std::thread(*this, args...) делает копию *this. Ну, пытается. Он не может этого сделать, потому что active_object является абстрактным классом (и если бы это было возможно, было бы хуже, поскольку active_object нарушает правило трех).

Вам необходимо использовать std::thread(std::ref(*this), args...), поэтому объект std::thread хранит ссылку, а не копию.

Смежные вопросы