使用 boost::mpl 的类型列表的排列
我正在尝试创建一个包含给定类型列表的排列的列表。
当我使用指定的列表而不是通过从实际输入中删除来生成新列表时,下面的代码似乎可以正常工作,但没有达到预期的结果。下面的 permutation_helper 和broken_helper 之间的差异证明了这一点。
有谁知道为什么 mpl::remove 在这种情况下似乎没有按预期运行?
#include <boost/mpl/list.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/push_front.hpp>
#include <boost/mpl/joint_view.hpp>
#include <boost/mpl/remove.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/equal.hpp>
namespace mpl = boost::mpl;
struct test_type1 {};
struct test_type2 {};
struct test_type3 {};
template< typename T >
struct permutations;
template <typename value>
struct permutations<mpl::list1< value > >: mpl::list1<mpl::list1< value > > {};
template< typename value, typename T>
struct permutation_helper:
mpl::transform< typename permutations<
mpl::list1<test_type3> >::type,
mpl::push_front< mpl::_1, value> > { };
template< typename value, typename T>
struct broken_helper:
mpl::transform< typename permutations<
mpl::remove<T, value> >::type,
mpl::push_front< mpl::_1, value> > { };
template< typename T >
struct permutations:
mpl::fold< T,
mpl::list0<>,
mpl::joint_view< mpl::_1,
broken_helper<mpl::_2, T > > > { };
typedef mpl::list2<test_type1, test_type2> typelist;
typedef permutations<typelist>::type perms;
int main() {
BOOST_MPL_ASSERT(( mpl::equal< perms, typelist > ));
return 0;
}
我使用断言来确定函数返回的内容,类型列表不是预期的结果。这是断言为broken_helper返回的消息:
testcase.cpp: In function ‘int main()’:
testcase.cpp:45: error: no matching function for call to ‘assertion_failed(mpl_::failed************ boost::mpl::equal<boost::mpl::joint_view<boost::mpl::joint_view<boost::mpl::list0<mpl_::na>, boost::mpl::l_end>, boost::mpl::l_end>, boost::mpl::list2<test_type1, test_type2>, boost::is_same<mpl_::arg<-0x00000000000000001>, mpl_::arg<-0x00000000000000001> > >::************)’
使用permutation_helper的输出是一个实际列表:
testcase.cpp: In function ‘int main()’:
testcase.cpp:45: error: no matching function for call to ‘assertion_failed(mpl_::failed************ boost::mpl::equal<boost::mpl::list2<test_type1, test_type2>, boost::mpl::joint_view<boost::mpl::joint_view<boost::mpl::list0<mpl_::na>, boost::mpl::l_item<mpl_::long_<1l>, boost::mpl::l_item<mpl_::long_<2l>, test_type1, boost::mpl::list1<test_type3> >, boost::mpl::l_end> >, boost::mpl::l_item<mpl_::long_<1l>, boost::mpl::l_item<mpl_::long_<2l>, test_type2, boost::mpl::list1<test_type3> >, boost::mpl::l_end> >, boost::is_same<mpl_::arg<-0x00000000000000001>, mpl_::arg<-0x00000000000000001> > >::************)’
I am trying to create a list containing the permutations of a given type list.
The below code seems to function, though without the intended result, when I use a specified list instead of generating a new list by removing from the actual input. This is demonstrated by the difference between permutation_helper and broken_helper below.
Does anyone know why mpl::remove
doesn't seem to function as expected in this circumstance?
#include <boost/mpl/list.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/push_front.hpp>
#include <boost/mpl/joint_view.hpp>
#include <boost/mpl/remove.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/equal.hpp>
namespace mpl = boost::mpl;
struct test_type1 {};
struct test_type2 {};
struct test_type3 {};
template< typename T >
struct permutations;
template <typename value>
struct permutations<mpl::list1< value > >: mpl::list1<mpl::list1< value > > {};
template< typename value, typename T>
struct permutation_helper:
mpl::transform< typename permutations<
mpl::list1<test_type3> >::type,
mpl::push_front< mpl::_1, value> > { };
template< typename value, typename T>
struct broken_helper:
mpl::transform< typename permutations<
mpl::remove<T, value> >::type,
mpl::push_front< mpl::_1, value> > { };
template< typename T >
struct permutations:
mpl::fold< T,
mpl::list0<>,
mpl::joint_view< mpl::_1,
broken_helper<mpl::_2, T > > > { };
typedef mpl::list2<test_type1, test_type2> typelist;
typedef permutations<typelist>::type perms;
int main() {
BOOST_MPL_ASSERT(( mpl::equal< perms, typelist > ));
return 0;
}
I used the assert to determine what is being returned from the function, typelist is not the expected result. This is the message the assert returns for broken_helper:
testcase.cpp: In function ‘int main()’:
testcase.cpp:45: error: no matching function for call to ‘assertion_failed(mpl_::failed************ boost::mpl::equal<boost::mpl::joint_view<boost::mpl::joint_view<boost::mpl::list0<mpl_::na>, boost::mpl::l_end>, boost::mpl::l_end>, boost::mpl::list2<test_type1, test_type2>, boost::is_same<mpl_::arg<-0x00000000000000001>, mpl_::arg<-0x00000000000000001> > >::************)’
The output using permutation_helper is an actual list:
testcase.cpp: In function ‘int main()’:
testcase.cpp:45: error: no matching function for call to ‘assertion_failed(mpl_::failed************ boost::mpl::equal<boost::mpl::list2<test_type1, test_type2>, boost::mpl::joint_view<boost::mpl::joint_view<boost::mpl::list0<mpl_::na>, boost::mpl::l_item<mpl_::long_<1l>, boost::mpl::l_item<mpl_::long_<2l>, test_type1, boost::mpl::list1<test_type3> >, boost::mpl::l_end> >, boost::mpl::l_item<mpl_::long_<1l>, boost::mpl::l_item<mpl_::long_<2l>, test_type2, boost::mpl::list1<test_type3> >, boost::mpl::l_end> >, boost::is_same<mpl_::arg<-0x00000000000000001>, mpl_::arg<-0x00000000000000001> > >::************)’
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
mpl::remove
工作正常。问题在于单例列表排列的模板:它仅捕获 mpl::list 的类型,而删除的结果具有另一种序列类型。换句话说,
mpl::remove
的结果是mpl::equal
到单例列表,但不是std::is_same
:可以通过专门化单例列表的模板来解决此问题,而不是基于确切的类型 mpl::list ,而是基于长度为 1 的属性:
顺便说一下,
会因完全相同的原因而失败。
mpl::remove
works correctly. The problem is with your template for permutations of singleton lists: it catches only types that arempl::list
s, while the result of remove has another sequence type.With other words, the result of
mpl::remove
ismpl::equal
to the singleton list, but notstd::is_same
:You can fix this problem by specializing your template for the singleton list not based on the exact type
mpl::list
, but on the property to have length 1:By the way,
will fail for exactly the same reasons.
作为 Lars 发布的答案的附录:
使用 joint_view 的给定排列算法似乎不适用于大小大于 2 的列表。我将其替换为 mpl::copy 到 front_inserter 中,并且该算法运行良好。
As an addendum to the answer that Lars posted:
The given permutation algorithm using joint_view does not seem to work on a list with a size greater than two. I replaced it with an mpl::copy into a front_inserter, and the algorithm worked perfectly.
您是否尝试过将代码放入库的相应命名空间中?
这可能听起来很愚蠢,但因为我已经解决了类似的问题(但没有使用 MPL!)。
Have you tried putting the code as belonging to the corresponding namespaces of the library?
It may sound stupid but since I already solved a similar problem (but was not using MPL!).