4

请参阅 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

为什么结果类型与“指针”类型不是 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

“在现实中”当它与指针不同时?

4

1 回答 1

7

再次感谢 @llonesmiz 使用 typeid() 漂亮地打印类型的代码,这有助于了解正在发生的事情。

所以看起来真正的结果类型取决于编译器(可能是 boost #ifdefs),英特尔编译器和 Visual Studio 将它转换回 std::vectorN<> 其中最大 N 是 boost 中的预定义数字(所以它在N 太大)。对于 g++,会生成一个重整类型(甚至是我的转换调用中的 2 种不同类型)。

所以我想通过 mpl::equal 检查类型很好(检查范围的元素)。如果所有类型都应该“真正”等效(std::is_same 成立),我想您需要手动将结果转换为可变参数模板类 std::tuple。

请参阅http://liveworkspace.org/code/3l8O9K 16 美元代码示例

或简而言之:

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*>

对于所有转换调用

于 2013-02-25T18:45:13.337 回答