Pregunta

Esta primera pieza ha sido resuelto por los comentarios de Eric por debajo, pero ha dado lugar a una cuestión secundaria que describo después de la regla horizontal. Gracias Eric!

Estoy tratando de pasar un functor que es una clase de plantilla para el método de la clase create_thread impulso thread_group junto con dos parámetros al funtor. Sin embargo, me parece que no puede ir más allá de mi error de compilación actual. Con el siguiente código:

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

También intentado typedef-ing 'tipo' como pensé que mi problema podría tener algo que ver con la plantilla Sig como el funtor sí está templated.

El error que estoy consiguiendo es:

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 montón de antemano preámbulo.

Gracias de antemano por cualquier ayuda!


Bueno yo he modificado el código en la toma de sugerencias de Eric por debajo de lo que resulta en el siguiente código:

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

Sin embargo, esto da lugar a otro error de compilación:

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

Parece haber definido invalidada si se result_type ahora está a la espera del operador () para devolver algo. He intentado volver result_type dentro de la función, pero esto también genera errores. Algunas ideas?

¿Fue útil?

Solución

Sig (o en su caso, simplemente typedef void result_type; es necesario.

IIRC, lambda :: bind hace copias de sus argumentos const.

Existe, pues, un problema con funtores con operador no const (). Esto se soluciona haciendo Ftor :: operador () const o por envolver (en doFtor ()), con _ftor impulso :: ref

Hay un problema similar con los iteradores. Envoltura de impulso :: ref aquí no trabajará directamente porque sería terminar con una referencia a un temporal. La solución más simple es modificar Ftor :: operador () para tomar sus argumentos por copia.

El más simple es, pues, modificar Ftor de manera que su operador () es const y que toma sus argumentos por copia:

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

Si realmente no puede hacer Ftor :: operador () const, podría modificar doFtor () de la siguiente manera (pero todavía es necesario hacer Ftor :: operador () tomar sus argumentos por copia):

_threads.create_thread(bind(boost::ref(_ftor), _list.begin(), _list.end()));
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top