提问人:sbi 提问时间:11/22/2013 最后编辑:Xeosbi 更新时间:11/22/2013 访问量:1192
如何在运行时在boost::fusion::vector中找到元素?
How to find an element in a boost::fusion::vector at runtime?
问:
我这里有一个通用状态机的专有实现,它使用 a 作为转换表:std::tr1::tuple
template<State StartState, Event TriggerEvent, State TargetState>
struct transition {...};
typedef std::tr1::tuple< transition< ready , run , running >
, transition< running , terminate, terminating >
, transition< terminating, finish , terminated >
> transition_table;
有一个函数
template<typename Transitions>
State find_next_state( State current
, Event event
, const Transitions& transition_table );
在给定当前状态和事件的转换表中查找下一个状态。
除了该平台的实现不支持超过 10 个项目外,这一切都工作正常。似乎也是如此,所以我正在尝试使用。但似乎 fusion 的find_if
只需要“一元 MPL Lambda 表达式”——我想,这只在编译时有效。tuple
boost::tuple
boost::fusion::vector
那么,鉴于上述情况,我该如何实现?find_next_state()
注意:
这是一个专有的嵌入式平台,只提供GCC 4.1.2,所以我们只能使用C++03+TR1。
答:
10赞
Xeo
11/22/2013
#1
编写自己的代码是相当微不足道的,除了“返回找到的值”部分。由于 a 是异构容器,因此没有要返回的单一正确类型。我想到的一个可能的解决方案是接受一个使用找到的值调用的延续函数:find_if
boost::fusion::vector
#include <boost/fusion/include/size.hpp>
#include <boost/fusion/include/at_c.hpp>
// private implementation details
namespace detail{
// shorthand ...
template<class S>
struct fusion_size{
static const unsigned value =
boost::fusion::result_of::size<S>::type::value;
};
// classic compile-time counter
template<unsigned> struct uint_{};
template<class Seq, class Pred, class F>
void find_if(Seq&, Pred const&, F, uint_<fusion_size<Seq>::value>, int)
{ /* reached the end, do nothing */ }
template<class Seq, class Pred, class F, unsigned I>
void find_if(Seq& s, Pred const& pred, F f, uint_<I>, long){
if(pred(boost::fusion::at_c<I>(s)))
{
f(boost::fusion::at_c<I>(s));
return; // bail as soon as we find it
}
find_if(s, pred, f, uint_<I+1>(), 0);
}
} // detail::
template<class Seq, class Pred, class F>
void find_if(Seq& s, Pred const& pred, F f){
detail::find_if(s, pred, f, detail::uint_<0>(), 0);
}
和参数以及参数只是为了消除 == 时的歧义,因为这两个函数同样可行。 类型使第一个重载(最后一个)成为首选。int
long
0
I+1
fusion_size<Seq>::value
0
int
评论
0赞
sbi
11/22/2013
这似乎与我正在寻找的东西足够接近,我可以对其进行调整。关于返回值,您可能想看看我的实际问题。 我总是需要返回一个枚举变量,所以这是小菜一碟。(如果我没有找到匹配项,我需要抛出一些变体,以及那些需要返回预定义值的变体,但那些我可以使用布尔参数甚至更多的重载来处理。这个重载的东西似乎有点过于聪明,我不确定我是否要把它放在这个代码库中,但在我按摩它来执行我的命令后,我会看看我是否需要它。:)
State
评论
find_if
tuple
transition
mpl::vector
mpl::for_each
transition_table
find_next_state()