如何使用Boost::Phoenix传递函数参数
How to pass a function in parameter with Boost::Phoenix?
这是我在这里的第一个帖子,如果我不尊重"方式和习俗",请原谅我:)
我是新使用Boost::Phoenix,我想传递一个函数给方法定义如下:
template <typename Selector>
Result Greedy (
const t_Capacity& capacity,
BTSSet stations,
BTSSet startSet)
{
//...
function <Selector> sel;
while ( !stations.empty() ) {
BTSSet::iterator currentStation = sel(stations);
// ...
}
// ...
}
我的选择器函数是:
struct rouletteWheelSelector {
typedef BTSSet::iterator result_type;
BTSSet::iterator operator () ( const BTSSet& stations ) {
// ...
}
};
但是我的编译器说没有办法从from 'typename detail::expression::function_eval<rouletteWheelSelector, set<BTS *, BTS_Cmp, allocator<BTS *> > >::type const'
转换为BTSSet::Iterator。
我的函子声明没问题吗?如何强制编译器推断出sel的正确返回类型?
有三个问题:
-
boost::phoenix::function<>
是惰性的,因此必须计算两次才能得到实际的结果。 -
rouletteWheelSelector::operator()
必须为const才能被boost::phoenix::function<>
使用。 -
sel
按值捕获stations
,因此返回一个销毁集合的迭代器; 使用
boost::phoenix::cref
捕获stations
。这段代码在vc++ 2010 SP1和Boost 1.47.0下编译和运行得很干净:
#include <memory>
#include <set>
#include <boost/phoenix.hpp>
struct BTS
{
explicit BTS(int const val_) : val(val_) { }
int val;
};
struct BTS_Cmp
{
typedef bool result_type;
bool operator ()(BTS const* const a, BTS const* const b) const
{
if (a && b)
return a->val < b->val;
if (!a && !b)
return false;
return !a;
}
};
typedef std::set<BTS*, BTS_Cmp> BTSSet;
struct rouletteWheelSelector
{
typedef BTSSet::iterator result_type;
BTSSet::iterator operator ()(BTSSet const& stations) const
{
return stations.begin();
}
};
template<typename Selector>
void Greedy(BTSSet stations)
{
namespace phx = boost::phoenix;
phx::function<Selector> sel;
while (!stations.empty())
{
BTSSet::iterator currentStation = sel(phx::cref(stations))();
std::auto_ptr<BTS> deleter(*currentStation);
stations.erase(currentStation);
}
}
int main()
{
BTSSet stations;
stations.insert(new BTS(1));
stations.insert(new BTS(2));
stations.insert(new BTS(3));
stations.insert(new BTS(4));
stations.insert(new BTS(5));
Greedy<rouletteWheelSelector>(stations);
}
如果您使用的是Phoenix v2而不是Phoenix v3,正如@jpalecek在他现在已删除的回答中正确指出的那样,您必须在rouletteWheelSelector
而不是result_type
中使用嵌套的result<>
模板:
struct rouletteWheelSelector
{
template<typename>
struct result
{
typedef BTSSet::iterator type;
};
BTSSet::iterator operator ()(BTSSet const& stations) const
{
return stations.begin();
}
};
然而,说了这么多,为什么你在这里使用boost::phoenix::function<>
?对于您的使用,没有它,Greedy<>
可以更容易(和有效)地实现:
template<typename Selector>
void Greedy(BTSSet stations)
{
Selector sel;
while (!stations.empty())
{
BTSSet::iterator currentStation = sel(stations);
std::auto_ptr<BTS> deleter(*currentStation);
stations.erase(currentStation);
}
}
相关文章:
- 如何在jthread中传递带有参数和stop_condition的函数
- 如何在C++中将迭代器作为函数参数传递
- void 函数可以传递值参数吗?
- 将函数参数完美转发到函数指针:按值传递呢?
- 为什么我不能将引用作为 std::async 的函数参数传递
- 节点插件 API 将数组作为函数参数传递
- 将字符串数组作为函数参数传递
- 在 C++ (Arduino) 中传递带有参数的函数作为参数
- 如何通过构造函数传递模板参数?
- C++ 如何根据作为输入传递的参数调用一个构造函数或另一个构造函数?
- 如何通过 C++ 中的函数参数传递初始值设定项列表的固定大小的初始值设定项列表?
- 我可以动态创建新地图并作为函数参数传递吗?
- 通过引用函数传递指针参数是什么意思?
- 如何在 arduino 中传递函数参数
- 按引用传递函数参数
- 'Invalid use of void expression'传递函数参数
- 通过指针传递函数参数
- 如何使用Boost::Phoenix传递函数参数
- 用户输入字符串流,然后需要转换为字符串来传递函数参数
- 传递函数参数时的c++执行顺序