2013-02-19 58 views
4

请参阅从升压下面的代码MPL转换文档:升压转换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 

为什么结果类型不是100%相同的“指针”型? 我认为这是因为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 

“现实中”,当它不是与指针?

+1

我猜这是'boost :: mpl :: vector'而不是'std :: vector'?使用''''指令时要小心,否则可能会发生冲突,或者在最坏的情况下代码难以遵循和维护。 – 2013-02-19 18:52:53

+2

http://liveworkspace.org/code/3l8O9K$0 – 2013-02-19 19:26:04

+0

@JoachimPileborg thx指出,它是关于'boost :: mpl :: vector'(代码来自教程,我不想修改它) 。请注意,我在代码的其余部分使用别名'namespace mpl = boost :: mpl;'。 – eci 2013-02-20 08:28:00

回答

7

再次感谢@llonesmiz为代码打印使用typeid(),这有助于了解发生了什么。

所以看起来真正的结果类型取决于编译器(可能是boost #ifdefs),intel编译器和visual studio将它转换回std :: vectorN <>其中最大N是boost中的预定义数字(所以它当N太大时不起作用)。 对于g ++,会生成一个mangled类型(即使我的变换调用有2种不同的类型)。

所以我想通过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*> 

用于ll转换调用

+1

非常干净的解决方案,用于将任何'boost :: mpl'序列转换为'std :: tuple'。 ** + 1 ** – etherice 2013-11-06 10:56:55

+0

这实际上是将任何'boost :: mpl'序列转换为特定序列类型的完美解决方案...就像'boost :: python :: bases',这是我的目标。不幸的是,我使用的VS2010不支持可变参数模板,但我可以通过'Boost.Preprocessor'解决这个问题。 – Kirinyale 2014-07-11 16:52:37