Domanda

Questo primo pezzo è stato risolto dai commenti di Eric inferiori ma ha portato su un problema secondario che descrivo, dopo la linea orizzontale. Grazie Eric!

Sto cercando di passare un funtore che è una classe su modelli al metodo create_thread di classe spinta thread_group insieme a due parametri al funtore. Tuttavia non riesco a ottenere oltre il mio errore di compilazione corrente. Con il codice qui sotto:

#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/thread.hpp>
#include <vector>

using namespace boost::lambda;
using namespace std;

namespace bl = boost::lambda;

template<typename ftor, typename data>
class Foo
{
public:
    explicit Foo()
    {
    }
    void doFtor ()
    {
        _threads.create_thread(bind(&Foo<ftor, data>::_ftor, _list.begin(), _list.end()));
        //_threads.create_thread(bind(_ftor, _list.begin(), _list.end()));
        _threads.join_all();
    }

private:
    boost::thread_group _threads;
    ftor _ftor;
    vector<data> _list;
};

template<typename data>
class Ftor
{
public:
    //template <class Args> struct sig { typedef void type; }

    explicit Ftor () {}

    void operator() (typename vector<data>::iterator &startItr, typename vector<data>::iterator &endItr)
    {
        for_each(startItr, endItr, cout << bl::_1 << constant("."));
    }
}

Ho anche provato typedef-ing 'tipo', come ho pensato che il mio problema potrebbe avere qualcosa a che fare con il modello Sig come il funtore stesso è basato su modelli.

L'errore che sto ottenendo è:

error: no matching function for call to ‘boost::lambda::function_adaptor<Ftor<int> Foo<Ftor<int>, int>::*>::apply(Ftor<int> Foo<Ftor<int>, int>::* const&, const __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int>> >&, const __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >&)’

con un gruppo di preambolo in anticipo.

Grazie in anticipo per qualsiasi aiuto!


Va bene ho modificato il codice tenendo in suggerimenti di Eric sotto conseguente il seguente codice:

#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/thread.hpp>
#include <vector>

using namespace boost::lambda;
using namespace std;

namespace bl = boost::lambda;

template<typename ftor, typename data>
class Foo
{
public:
    explicit Foo()
    {
    }
    void doFtor ()
    {
        _threads.create_thread(bl::bind(boost::ref(_ftor), _list.begin(), _list.end()));
        _threads.join_all();
    }

private:
    boost::thread_group _threads;
    ftor _ftor;
    vector<data> _list;
};

template<typename data>
class Ftor
{
public:
    typedef void result_type;

    explicit Ftor () {}

    result_type operator() (typename vector<data>::iterator &startItr, typename vector<data>::iterator &endItr)
    {
        for_each(startItr, endItr, cout << bl::_1 << constant("."));
        return ;
    }
};

Tuttavia questo si traduce in un altro errore di compilazione:

/usr/local/include/boost/lambda/detail/function_adaptors.hpp:45: error: no match for call to ‘(Ftor<int>) (const __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >&, const __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >&)’
ftor.h:41: note: candidates are: void Ftor<data>::operator()(typename std::vector<data, std::allocator<_CharT> >::iterator&, typename std::vector<data, std::allocator<_CharT> >::iterator&) [with data = int]
/usr/local/include/boost/lambda/detail/function_adaptors.hpp:45: error: return-statement with a value, in function returning 'void'

Sembra aver definito decadere se result_type è ora aspetta l'operatore () per restituire qualcosa. Ho provato tornando result_type dall'interno della funzione ma anche provocato errori. Tutte le idee?

È stato utile?

Soluzione

Sig (o nel vostro caso, è sufficiente typedef void result_type; è necessario.

IIRC, lambda :: bind crea copie const dei suoi argomenti.

Esiste dunque un problema con functors con operatore non-const (). Questo è risolto facendo Ftor :: operator () const o avvolgendo (in Dottore ()), _ftor con boost :: ref

C'è un problema simile con gli iteratori. Wrapping in boost :: Rif qui non lavorerà direttamente perché sarebbe finire con un riferimento a una temporanea. La soluzione più semplice è quella di modificare Ftor :: operator () a muovere i suoi argomenti per copia.

Il più semplice è quindi di modificare Ftor modo che il suo operatore () è const e Prende l'argomenti copiando:

void operator() (typename vector<data>::iterator startItr, typename vector<data>::iterator endItr)const

Se proprio non potete fare Ftor :: operator () const, si potrebbe modificare Dottore () come segue (ma è ancora necessario fare Ftor :: operator () prendere i suoi argomenti per copia):

_threads.create_thread(bind(boost::ref(_ftor), _list.begin(), _list.end()));
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top