3つの問題があります。
boost::phoenix::function<>
怠惰なので、実際の結果を得るには2回評価する必要があります。
rouletteWheelSelector::operator()
で使用するには、constである必要がありますboost::phoenix::function<>
。
sel
値でキャプチャstations
し、その結果、イテレータを破棄されたセットに戻します。const-referenceによるboost::phoenix::cref
キャプチャに使用します。stations
このコードは、VC ++ 2010SP1とBoost1.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);
}
@jpalecekが削除された回答に正しく記載されているように、Phoenixv3ではなくPhoenixv2を使用している場合は、 :ではなく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);
}
}