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 で operator() を非純粋仮想関数にすると、コンパイルは行われますが、std::thread() の構築でセグメンテーション エラーが発生します。

4

1 に答える 1

3

std::thread( *this, args...) makes a copy of *this. Well, tries to. It can't do so because active_object is an abstract class (and if it was possible, it would be worse since active_object violates the rule of three).

You need to use std::thread(std::ref(*this), args...) so the std::thread object stores a reference, not a copy.

于 2013-09-18T10:36:22.390 に答える