gpt4 book ai didi

lambda 表达式中的 C++ 模板仿函数

转载 作者:太空狗 更新时间:2023-10-29 23:20:16 24 4
gpt4 key购买 nike

第一部分已由 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("."));
}
}

我还尝试了 typedef-ing '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 拷贝。

因此,带有非常量 operator() 的仿函数存在问题。这可以通过包装(在 doFtor() 中)使 Ftor::operator() const 来解决,_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() 常量,你可以修改 doFtor() 如下(但仍然有必要使 Ftor::operator() 以复制方式获取其参数):

_threads.create_thread(bind(boost::ref(_ftor), _list.begin(), _list.end()));

关于lambda 表达式中的 C++ 模板仿函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2343719/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com