Problem mit boost::bind und boost::thread



  • Hallo,

    ich versuche mich gerade in boost::thread und boost::bind einzuarbeiten,
    aber irgendwie will das nicht so klappen.

    Damit ich nicht immer wieder neuen Code
    schreiben muss, habe ich mir eine Template-Klasse gebaut,
    die über Vererbung dann die jeweils spezifische Logik
    beinhaltet.
    Im Beispiel wäre dann in der Klasse 'Specialized' die direkte Implementierung.
    Aber ich kriege das mit Threads und boost::bind nicht zum Laufen.
    Was mache ich falsch?

    Hier mal der Code:

    #include <iostream>
    #include <boost/thread.hpp>
    
    using namespace std;
    
    template<typename T>
    class Base{
    public:
    	Base(){}
    	virtual ~Base(){}
    	virtual void processBase(const T& item){this->doProcess(item);}
    protected:
    	virtual void doProcess(const T& item)=0;
    };
    
    template<typename T>
    class Derived: public Base<T> {
    public:
    	Derived():Base<T>(){}
    	virtual ~Derived(){}
    	void processDerived(const T& item){this->processBase(item);}
    
    protected:
    	void processBase(const T& item){Base<T>::processBase(item);}
    };
    
    class Specialized: public Derived<int>{
    public:
    	Specialized():Derived<int>(){}
    	~Specialized(){}
    protected:
    	void doProcess(const int& item){}
    };
    
    int main() {
    
    	boost::thread_group group;
    	int value=6;
    	group.add_thread(new boost::thread(boost::bind(&Specialized::processDerived,&value)));
    	return 0;
    }
    

    Wenn ich den Code kompilieren lasse, bekomme ich folgende Fehlermeldung:

    In file included from /usr/include/boost/mem_fn.hpp:22:0,
    from /usr/include/boost/bind/bind.hpp:26,
    from /usr/include/boost/bind.hpp:22,
    from /usr/include/boost/thread/detail/thread.hpp:20,
    from /usr/include/boost/thread/thread.hpp:22,
    from /usr/include/boost/thread.hpp:13,
    from ../src/test.cpp:12:
    /usr/include/boost/bind/mem_fn.hpp: In member function ‘const R& boost::_mfi::dm<R, T>::call(U&, const void*) const [with U = int* const, R = void(const int&), T = Derived<int>]’:
    /usr/include/boost/bind/mem_fn.hpp:352:26: instantiated from ‘const R& boost::_mfi::dm<R, T>::operator()(const U&) const [with U = int*, R = void(const int&), T = Derived<int>]’
    /usr/include/boost/bind/bind.hpp:243:60: instantiated from ‘R boost::_bi::list1<A1>::operator()(boost::_bi::type<R>, F&, A&, long int) [with R = void (&)(const int&),
    F = boost::_mfi::dm<void(const int&), Derived<int> >, A = boost::_bi::list0, A1 = boost::_bi::value<int*>]’
    /usr/include/boost/bind/bind_template.hpp:20:59: instantiated from ‘boost::_bi::bind_t<R, F, L>::result_type boost::_bi::bind_t<R, F, L>::operator()() [with R = void (&)(const int&), F = boost::_mfi::dm<void(const int&), Derived<int> >, L = boost::_bi::list1<boost::_bi::value<int*> >, boost::_bi::bind_t<R, F, L>::result_type = void (&)(const int&)]’
    /usr/include/boost/thread/detail/thread.hpp:56:17: instantiated from ‘void boost::detail::thread_data<F>::run() [with F = boost::_bi::bind_t<void (&)(const int&), boost::_mfi::dm<void(const int&),
    Derived<int> >, boost::_bi::list1<boost::_bi::value<int*> > >]’
    ../src/test.cpp:57:1: instantiated from here
    /usr/include/boost/bind/mem_fn.hpp:333:36: error: cannot apply member pointer ‘((const boost::_mfi::dm<void(const int&), Derived<int> >)this)->boost::mfi::dm<void(const int&),
    Derived<int> >::f
    ’ to ‘
    boost::get_pointer [with T = int](u)’, which is of non-class type ‘int’
    make: *** [src/test.o] Fehler 1

    Was muss ich an boost::bind übergeben, damit ein Thread mit der Klasse Specialized gestartet wird?



  • Du musst bind noch ein Objekt mitgeben auf dem die gebundene Funktion aufgerufen werden kann. Dieses Objekt musst Du als 2ter Parameter beim bind angeben.



  • boost.bind fehlt ein Objekt Deiner Specialized-Klasse. Schließlich ist processDerived eine Memberfunktion. Das ändert sich auch Durch bind nicht.



  • Super, das klappt. 🙂

    Danke schön.



  • Nimm statt der void processDerived Methode doch den () Operator und übergib Werte im Konstruktor.

    template<typename T>
    class Derived // Brauch gar keine Basisklasse... : public Base<T> 
    {
    public:
        Derived(const T& item) : item_(item){}
        void operator(){process(item_);}
    
    private:
        virtual void process(const T& item)  // kann man überschreiben wenn es denn sinnvoll ist.
        {/*pipapo*/}
    
        T item_;
    };
    

Anmelden zum Antworten