[英]C++ templated functor in lambda expression
第一篇文章已經通過Eric的評論在下面得到了解決,但卻引發了我在橫向規則之后描述的第二個問題。 謝謝埃里克!
我試圖將一個模板類的仿函數傳遞給boost 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("."));
}
}
我也嘗試過typedefing'type',因為我認為我的問題可能與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> > >&)’
事先用一堆序言。
在此先感謝您的幫助!
好的,我已經修改了以下Eric建議中的代碼,導致以下代碼:
#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,但這也產生了錯誤。 有任何想法嗎?
Sig
(或者在你的情況下,只需要typedef void result_type;
是必要的。
IIRC,lambda :: bind生成其參數的const副本。
因此,使用非const運算符()的仿函數存在問題。 這是通過制作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()));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.