3

この最初の部分は、以下のエリックのコメントによって解決されましたが、水平ルールの後に説明する二次的な問題につながりました。ありがとうエリック!

テンプレート化されたクラスであるファンクターを、ファンクターへの 2 つのパラメーターと共にブースト thread_group クラスの create_thread メソッドに渡そうとしています。ただし、現在のコンパイル エラーを超えることはできないようです。以下のコードで:

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

ファンクター自体がテンプレート化されているため、私の問題はSigテンプレートに関係している可能性があると考えたため、「タイプ」のtypedefも試しました。

私が得ているエラーは次のとおりです。

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'

void を result_type として定義したようで、 operator() が何かを返すことを期待しています。関数内から result_type を返そうとしましたが、これもエラーが発生しました。何か案は?

4

1 に答える 1

0

Sig(またはあなたの場合、単にtypedef void result_type;必要です。

IIRC、lambda::bind はその引数の const コピーを作成します。

したがって、非 const operator() を持つファンクターには問題があります。これは、Ftor::operator()const を作成する、(doFtor() で) _ftor を boost::ref でラップすることによって解決されます。

イテレータにも同様の問題があります。ここで boost::ref にラップすると、一時的な参照を使用することになるため、直接は機能しません。より簡単な解決策は、Ftor::operator() を変更して、その引数をコピーで取得することです。

したがって、最も簡単な方法は Ftor を変更して、その operator() が 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()));
于 2010-02-26T19:09:44.243 に答える