Frage

Das erste Stück wurde von Erics Kommentaren unten gelöst, sondern hat sich auf eine zweitrangige Frage geführt, dass ich nach der horizontalen Regel beschreiben. Dank Eric!

Ich versuche, ein Funktor zu übergeben, die eine Templat-Klasse an die create_thread Methode der Anhebung thread_group Klasse zusammen mit zwei Parametern an die Funktor ist. Allerdings kann ich nicht scheinen, über meine aktuellen Compiler-Fehler zu erhalten. Mit dem folgenden Code:

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

ich auch typedef-ing ‚Typ‘ versuchte, wie ich dachte, mein Problem etwas mit der Sig-Vorlage zu tun haben könnte, wie der Funktor selbst als Templat wird.

Der Fehler Ich erhalte ist:

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

mit einem Bündel von Präambel voraus.

Vielen Dank im Voraus für jede Hilfe!


Okay, ich habe den Code Mitnahmen in Erics Vorschlägen geändert in dem folgenden Code unter resultierenden:

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

Dies führt jedoch in einem anderen Compiler-Fehler:

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

Es scheint, definiert zu haben Leere als result_type es nun den Bediener erwartet () etwas zurück. Ich versuchte Rückkehr result_type innerhalb der Funktion aber auch Fehler erzeugt. Irgendwelche Ideen?

War es hilfreich?

Lösung

Sig (oder in Ihrem Fall einfach typedef void result_type; notwendig ist.

IIRC, lambda :: bind macht const Kopien ihrer Argumente.

Es ist also ein Problem mit functors mit nicht-const-Operator (). Dies wird gelöst, indem Ftor :: operator () const oder durch Verpackung (in doFtor ()), _ftor mit boost :: ref

Es gibt ein ähnliches Problem mit den Iteratoren. Wrapping in boost :: ref hier nicht direkt arbeiten, weil es einen Verweis auf eine vorübergehende würde am Ende mit. Die einfachere Lösung ist Ftor :: operator (), um seine Argumente zu kopieren.

zu ändern

Am einfachsten ist es somit Ftor, so dass dessen Operator () ist const und es dauert seine Argumente Kopie zu ändern:

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

Wenn Sie wirklich nicht Ftor :: operator () const machen, könnten Sie doFtor ändern () wie folgt (aber es ist immer noch notwendig Ftor zu machen :: operator (), um seine Argumente kopieren):

_threads.create_thread(bind(boost::ref(_ftor), _list.begin(), _list.end()));
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top