Question

Cette première pièce a été résolu par les commentaires ci-dessous de Eric, mais a conduit sur une question secondaire que je décris après la règle horizontale. Merci Eric!

Je suis en train de passer un foncteur qui est une classe à la méthode basé sur un modèle de create_thread de classe boost thread_group avec deux paramètres à la foncteur. Cependant, je ne peux pas sembler aller au-delà de mon erreur de compilation en cours. Avec le code ci-dessous:

#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("."));
    }
}

J'ai aussi essayé typedef-ing « type » que je pensais que mon problème pourrait avoir quelque chose à voir avec le Sig modèle que le foncteur lui-même est basé sur un modèle.

L'erreur que je reçois est:

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> > >&)’

avec un groupe de préambule au préalable.

Merci d'avance pour toute aide!


D'accord, je l'ai modifié le code prenant dans les suggestions ci-dessous Eric résultant dans le code suivant:

#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 ;
    }
};

Cependant il en résulte une erreur de compilation:

/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'

Il semble avoir défini vide comme result_type il attend maintenant de retourner quelque chose à l'opérateur (). J'ai essayé de revenir result_type à partir de la fonction mais aussi des erreurs générées. Toutes les idées?

Était-ce utile?

La solution

Sig (ou dans votre cas, il suffit de typedef void result_type; est nécessaire.

IIRC, lambda :: bind fait des copies const de ses arguments.

Il y a donc un problème avec foncteurs avec opérateur non const (). Ceci est résolu en faisant Ftor :: operator () const ou en enveloppant (en doFtor ()), _ftor avec boost :: ref

Il y a un problème similaire avec les itérateurs. Aluminuim boost :: ref ici ne fonctionnera pas directement parce qu'elle mettrait fin à l'aide d'une référence à un temporaire. La solution plus simple est de modifier l'opérateur de Ftor () pour prendre ses arguments par copie.

La plus simple consiste donc à modifier Ftor de telle sorte que son opérateur () est const et il prend ses arguments par copie:

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

Si vous ne pouvez vraiment pas faire Ftor :: operator () const, vous pouvez modifier doFtor () comme suit (mais il est encore nécessaire de faire Ftor :: operator () prendre ses arguments par copie):

_threads.create_thread(bind(boost::ref(_ftor), _list.begin(), _list.end()));
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top