请参阅boost mpl转换文档中的以下代码:
typedef vector<char,short,int,long,float,double> types;
typedef vector<char*,short*,int*,long*,float*,double*> pointers;
typedef transform< types,boost::add_pointer<_1> >::type result;
BOOST_STATIC_ASSERT(( equal<result,pointers>::value ));
我想了解boost::mpl
的类型系统和“它实际上是如何工作的”。
据我所知mpl::equal
只是比较以下两个序列的元素而不是整个序列类型本身。
我不明白为什么以下失败:
BOOST_STATIC_ASSERT(( std::is_same<result,pointers>::value )); //< assert fails
为什么结果类型与“指针”类型不完全相同? 我假设这是某种程度上因为mpl正在执行变换懒惰或结果只是一个序列而不再是一个向量? 有可能以某种方式迫使mpl不再懒惰并获得100%相同的类型(我可以用这个结果自己写一个转换函数,但我想知道如何在mpl中做到这一点)?
我已经尝试过一些像将结果插入新的向量但没有成功:
BOOST_STATIC_ASSERT(( std::is_same<
mpl::insert_range< mpl::vector<>, mpl::begin<mpl::vector<> >::type,
result >::type, pointers >::value )); //< assert fails too
另外,我尝试在转换函数中使用back_insert,它也失败了:
typedef transform< types,boost::add_pointer<_1>,
mpl::back_inserter< mpl::vector< > > >::type result_new;
BOOST_STATIC_ASSERT(( std::is_same<result_new,pointers>::value )); //< fails...
阅读“文档”对我没有帮助。 那么,是否有可能通过mpl变换(或任何其他变换序列函数)获得100%相同的类型?什么是类型
的结果result
“实际上”当它不是带指针的is_same时?
答案 0 :(得分:7)
再次感谢@llonesmiz代码,使用typeid()来打印类型,这有助于理解发生了什么。
所以看起来真正的结果类型取决于编译器(可能是boost #ifdefs),intel编译器和visual studio将它转换回std :: vectorN&lt;&gt;其中最大N是boost中的预定义数字(因此当N太大时它不起作用)。 对于g ++,会生成一个受损的类型(甚至是我的转换调用中的两种不同类型)。
所以我想通过mpl :: equal检查类型很好(检查范围的元素)。 如果所有类型都应该“真正”等价(std :: is_same成立),我猜你需要手动将结果转换为可变参数模板类std :: tuple。
请参阅http://liveworkspace.org/code/3l8O9K $ 16 Code Sample
或简称:
template < class T, class R >
struct ToStdTuple;
template < class... TTypes, class X >
struct ToStdTuple< std::tuple< TTypes... >, X >
{
typedef std::tuple< TTypes..., X > type;
};
然后
// typedef mpl::vector<char,short,int,long,float,double> types;
// typedef mpl::transform< types,boost::add_pointer<mpl::_1> >::type result;
typedef mpl::fold< result, std::tuple<>,
ToStdTuple< mpl::_1, mpl::_2 > >::type result_normalized;
导致
std::tuple<char*, short*, int*, long*, float*, double*>
用于所有转换调用