سؤال

تم حل هذه القطعة الأولى من خلال تعليقات إريك أدناه ولكنها أدت إلى قضية ثانوية أصفها بعد القاعدة الأفقية. شكرا إريك!

أحاول تمرير مجموعة functor التي هي فئة templated إلى طريقة create_thread لفئة Boost Thread_group جنبا إلى جنب مع معلمتين إلى functor. ومع ذلك ، لا يمكنني أن أتجاوز خطأ التجميع الحالي. مع الرمز أدناه:

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

لقد جربت أيضًا typedef-ing "نوع" حيث اعتقدت أن مشكلتي قد تكون لها علاقة بقالب SIG لأن المسلح نفسه قد تم تنظيمه.

الخطأ الذي أحصل عليه هو:

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

مع حفنة من الديباجة مسبقا.

شكرا مقدما على أي مساعدة!


حسنًا ، لقد قمت بتعديل الكود الذي يأخذ اقتراحات إريك أدناه مما أدى إلى الكود التالي:

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

ومع ذلك ، ينتج عن هذا خطأ في ترجمة آخر:

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

يبدو أنه تم تحديد الفراغ كنتيجة _type ، يتوقع الآن أن يعيد المشغل () شيئًا ما. حاولت إرجاع result_type من داخل الوظيفة ، لكن هذا أدى أيضًا إلى وجود أخطاء. أيه أفكار؟

هل كانت مفيدة؟

المحلول

Sig (أو في حالتك ، ببساطة typedef void result_type; مهم.

IIRC ، lambda :: bind يجعل نسخ كونست من حججها.

وهكذا هناك مشكلة مع المرتبات مع المشغل غير المشترك (). يتم حل هذا عن طريق صنع Ftor :: Operator () const أو عن طريق التفاف (في Doftor ()) ، _ftor مع Boost :: Ref

هناك مشكلة مماثلة مع التكرار. الالتفاف في Boost :: Ref هنا لن يعمل مباشرة لأنه سينتهي باستخدام إشارة إلى مؤقت. الحل البسيط هو تعديل FTOR :: Operator () لاتخاذ وسيطاته عن طريق النسخ.

وبالتالي ، فإن أبسط هو تعديل ftor بحيث يكون مشغله () هو const و يأخذ حججها بالنسخ:

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

إذا لم تتمكن حقًا من جعل Ftor :: Operator () const ، فيمكنك تعديل Doftor () على النحو التالي (ولكن لا يزال من الضروري جعل Ftor :: Operator () أخذ وسائطه بالنسخ):

_threads.create_thread(bind(boost::ref(_ftor), _list.begin(), _list.end()));
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top