gpt4 book ai didi

c++ - 如何使用 Boost::Phoenix 传递函数参数?

转载 作者:太空宇宙 更新时间:2023-11-04 12:15:48 26 4
gpt4 key购买 nike

这是我在这里的第一篇文章,如果我不尊重“风俗习惯”,请多多包涵:)

我是 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 的正确返回类型?

谢谢!

最佳答案

你有三个问题:

  1. boost::phoenix::function<>是惰性的,因此必须对其进行两次评估才能获得实际结果。
  2. rouletteWheelSelector::operator()必须是 const 才能被 boost::phoenix::function<> 使用.
  3. 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 在他现已删除的答案中正确指出的那样,您必须使用嵌套的 result<> rouletteWheelSelector 内的模板而不是 result_type :

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

关于c++ - 如何使用 Boost::Phoenix 传递函数参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7759508/

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