C++ 将mpl序列转换为trie
问题看起来很简单,基本上我有一系列的序列,比如:C++ 将mpl序列转换为trie,c++,templates,boost,template-meta-programming,boost-mpl,C++,Templates,Boost,Template Meta Programming,Boost Mpl,问题看起来很简单,基本上我有一系列的序列,比如: typedef mpl::vector< mpl::vector<mpl::_1, mpl::_2>, mpl::vector<mpl::_1, mpl::_2, mpl::_3>, mpl::vector<mpl::_2, mpl::_1>, mpl::vector<mpl::_2, mpl::_2>, mpl::vector<mpl::_2, mpl::_2, m
typedef mpl::vector<
mpl::vector<mpl::_1, mpl::_2>,
mpl::vector<mpl::_1, mpl::_2, mpl::_3>,
mpl::vector<mpl::_2, mpl::_1>,
mpl::vector<mpl::_2, mpl::_2>,
mpl::vector<mpl::_2, mpl::_2, mpl::_3>
> seq;
mpl::map<
mpl::pair<mpl::_1,
mpl::map<
mpl::pair<mpl::_2,
mpl::map<
mpl::pair<TERMINAL, T>,
mpl::pair<mpl::_3,
mpl::map<
mpl::pair<TERMINAL, T>
>
>
>
>
>
>
mpl::pair<mpl::_2,
mpl::map<
mpl::pair<mpl::_1,
mpl::map<
mpl::pair<TERMINAL, T>
>
>,
mpl::pair<mpl::_2,
mpl::map<
mpl::pair<TERMINAL, T>,
mpl::pair<mpl::_3,
mpl::map<
mpl::pair<TERMINAL, T>
>
>
>
>
>
>
>
typedef mpl::vector<
向量,
向量,
向量,
向量,
向量
>序号;
我想做的是将其转换为trie,最终结果如下:
typedef mpl::vector<
mpl::vector<mpl::_1, mpl::_2>,
mpl::vector<mpl::_1, mpl::_2, mpl::_3>,
mpl::vector<mpl::_2, mpl::_1>,
mpl::vector<mpl::_2, mpl::_2>,
mpl::vector<mpl::_2, mpl::_2, mpl::_3>
> seq;
mpl::map<
mpl::pair<mpl::_1,
mpl::map<
mpl::pair<mpl::_2,
mpl::map<
mpl::pair<TERMINAL, T>,
mpl::pair<mpl::_3,
mpl::map<
mpl::pair<TERMINAL, T>
>
>
>
>
>
>
mpl::pair<mpl::_2,
mpl::map<
mpl::pair<mpl::_1,
mpl::map<
mpl::pair<TERMINAL, T>
>
>,
mpl::pair<mpl::_2,
mpl::map<
mpl::pair<TERMINAL, T>,
mpl::pair<mpl::_3,
mpl::map<
mpl::pair<TERMINAL, T>
>
>
>
>
>
>
>
mpl::map<
mpl::pair
>
>
>
mpl::pair,
mpl::pair
>
>
>
>
>
所以,问题是,这可能吗(我认为不可能)?如果可能的话,我错过了哪些黑暗咒语
编辑:如果上述从序列序列到trie的转换不清楚,让我看看是否可以用简单的英语来说明(通常更难)。基本上,主序列中的每个序列都由一些类型组成(\u 1
,\u 2
等)。转换后的版本是trie,其中常见前缀被折叠。附件中的图片可能有帮助
编辑2:感谢@Yakk,希望现在问题更清楚了…所以答案是“是的,这是可能的”
将添加内容写入目录。它接受一个可能为空的trie和一个元素(一系列类型),并返回一个添加了该元素的trie
在一个空的trie和一些序列上,以及在一些其他手工制作的情况下,测试add_to_trie。通用前缀:(“A”)(“A”、“B”)、无通用前缀:(“A”、“A”)(“B”、“A”)、较短的无通用前缀:(“A”、“B”)(“B”)、同一事物的两份副本:(“A”)(“A”)等
写积累。它接受一个值、一个二进制函子和一个序列。如果对序列的每个元素s应用value=functor(value,s),则返回value
通过将1到5相加并打印结果来累积测试
把两者组合起来
这可能会破坏模板递归堆栈,每个步骤都很容易编写正确,但它会工作
首先在字符串上编写上述操作可能会有所帮助。然后使功能正常运行。然后转换为对类型进行操作
我敢打赌,即使是钱,boost
也有一个合适的累加
。好了:
struct Terminal;
template < typename Trie, typename First, typename Last,
typename Enable = void >
struct insertInTrie_impl
{
typedef typename
mpl::deref<First>::type key;
typedef typename
mpl::at<
Trie,
key
>::type subTrieOrVoid; // would be easier if "at" supported Default
typedef typename
mpl::if_<
boost::is_same< subTrieOrVoid, mpl::void_ >,
mpl::map<>,
subTrieOrVoid
>::type subTrie;
typedef typename
mpl::insert<
Trie,
mpl::pair<
key, typename
insertInTrie_impl<
subTrie, typename
mpl::next<First>::type,
Last
>::type
>
>::type type;
};
template < typename Trie, typename First, typename Last >
struct insertInTrie_impl< Trie, First, Last, typename
boost::enable_if< boost::is_same<First, Last> >::type >
: mpl::insert<
Trie,
mpl::pair< Terminal, Terminal >
// I'm not sure what you want in your terminal node
>
{};
template < typename Trie, typename Seq >
struct insertInTrie
: insertInTrie_impl<
Trie, typename
mpl::begin<Seq>::type, typename
mpl::end<Seq>::type
>
{};
template < typename SeqOfSeq >
struct constructTrie
: mpl::fold<
SeqOfSeq,
mpl::map<>,
insertInTrie< mpl::_1, mpl::_2 >
>
{};
最后,使用以下示例:
int main()
{
typedef mpl::vector<
mpl::vector<mpl::_1, mpl::_2>,
mpl::vector<mpl::_1, mpl::_2, mpl::_3>,
mpl::vector<mpl::_2, mpl::_1>,
mpl::vector<mpl::_2, mpl::_2>,
mpl::vector<mpl::_2, mpl::_2, mpl::_3>
> seqOfSeq;
typedef constructTrie< seqOfSeq >::type bigTrie;
BOOST_MPL_ASSERT((
mpl::has_key<
mpl::at<
mpl::at<
bigTrie,
mpl::_1
>::type,
mpl::_2
>::type,
Terminal
> ));
BOOST_MPL_ASSERT((
mpl::has_key<
mpl::at<
mpl::at<
mpl::at<
bigTrie,
mpl::_1
>::type,
mpl::_2
>::type,
mpl::_3
>::type,
Terminal
> ));
BOOST_MPL_ASSERT((
mpl::has_key<
mpl::at<
mpl::at<
bigTrie,
mpl::_2
>::type,
mpl::_2
>::type,
Terminal
> ));
}
intmain()
{
typedefmpl::vector<
向量,
向量,
向量,
向量,
向量
>seqOfSeq;
typedef-constructrie:类型bigTrie;
增强MPL断言((
mpl::具有\u密钥<
mpl::at<
mpl::at<
比格特里,
mpl::_1
>::类型,
mpl::_2
>::类型,
终点站
> ));
增强MPL断言((
mpl::具有\u密钥<
mpl::at<
mpl::at<
mpl::at<
比格特里,
mpl::_1
>::类型,
mpl::_2
>::类型,
mpl::_3
>::类型,
终点站
> ));
增强MPL断言((
mpl::具有\u密钥<
mpl::at<
mpl::at<
比格特里,
mpl::_2
>::类型,
mpl::_2
>::类型,
终点站
> ));
}
我看不出您想要的转换是什么。请提供实际的具体示例和伪代码。@Yakk,已更新-这有帮助吗?基本上,我试图在图片中构建给定的树,这样我就可以使用给定的序列(mpl::vector
来获取终端
类型的实例)进行导航。如果缺少子序列1和4,结构是否与生成的结构等效?如果我理解正确,主序列是一个路径序列,节点是在尚未出现时生成的(路径mpl::vector
和mpl::vector
缺失)@AndyProwl,最终结果应该允许您查找任何给定序列以获得terminal
类型,如果缺失,我不明白这怎么可能?@Nim:我想知道的是,从主序列中删除第一个和第四个序列是否会产生相同的结果。在我看来,这些序列是多余的,还是不是?如果没有,为什么mpl::vector
和mpl::vector
也不存在呢?boost
确实提供了累积
,我想我现在的问题是如何将咒语按正确的顺序排列以获得最终结果…+1,这将花费我一天的时间来解决这个问题!;)@尼姆:一旦你习惯了元函数的工作方式,其实没那么难。我添加了一些伪代码,以一种更简单的方式解释mpl代码。很好,我实现了这一点,终端类型可以作为最后一个参数在嵌套序列中传递,我只需添加另一个间接寻址,将其从序列中剥离并传播。再次感谢!