2014-10-31 57 views
3

我想将mpl::vector中的每个元素乘以int。 首先,将int_int相乘的元函数。使用自己的函数转换mpl向量

template <int i> 
struct multiply_scalar 
{ 
    template<typename T> struct apply 
    { 
     typedef int_<(T::value * i)> type; 
    }; 
}; 

这里是我想要打的电话。

typedef vector<int_<3>, int_<4> > my_vec; 
typedef typename transform< my_vec, multiply_scalar<2> >::type my_vec_2; 

typedef vector<int_<6>, int_<8> > my_vec_3; 

BOOST_MPL_ASSERT((boost::is_same< my_vec_2, my_vec_3 >)); //Fails 
//type of my_vec2 is: boost::mpl::v_item<mpl_::int_<8>, boost::mpl::v_item<mpl_::int_<6>, boost::mpl::vector0<mpl_::na>, 0>, 0> 

为什么不是由此产生的向量只是一个vector<int_<6>, int_<8>>?我是否认为它错了?元函数或变换可能没有以正确的方式应用。

回答

5

主要是因为在C++ 03时,在MPL 的作家一些执行问题不得不使用非显而易见的技术代表序列,其中之一是 的类型,如

boost::mpl::vector0<> 
boost::mpl::vector1<T> 
boost::mpl::vector2<T, U> 
... etc 

使用而不是简单地写作

boost::mpl::vector<> 
boost::mpl::vector<T> 
boost::mpl::vector<T, U> 

就像在C++ 11及更高版本中使用可变参数模板一样。另一种技术是 当你在一个载体, 插入的东西创造某种反向链接列表的是你在找什么在你的例子:

boost::mpl::v_item<mpl_::int_<8>, // 2nd element 
    boost::mpl::v_item<mpl_::int_<6>, // 1st element 
     boost::mpl::vector0<mpl_::na>, 0>, 0> // empty list 

正因为如此,在documentationboost::mpl::transform做没有指定究竟是什么是boost::mpl::transform<s,op,in>::type的类型。 实际上,它只能保证它是一种相当于

typedef lambda<op>::type f; 
typedef lambda<in::operation>::type in_op; 

typedef fold< 
     s 
    , in::state 
    , bind< in_op, _1, bind<f, _2> > 
    >::type r; // <-- the return type is equivalent to this r 

这可能不会帮助你,除非你已经知道了MPL不够好, 你不问SO上关于它的问题;-),所以基本上这意味着它返回 一个新的类型,就像boost::mpl::vector,除了它的实际类型可能是 是我上面显示的任何东西。特别是,这种类型保证是Forward Sequence概念的型号 。

当您使用boost::is_same<T, U>,你实际上问 是否TU正是同一类型。您现在应该清楚地看到为什么这不是您实际需要的 。相反,你想做一些深的两个序列的比较,这两个序列都代表了载体。要检查两个正向序列是否相等,您必须改用算法。以下将起作用:

#include <boost/mpl/assert.hpp> 
#include <boost/mpl/equal.hpp> 
#include <boost/mpl/int.hpp> 
#include <boost/mpl/transform.hpp> 
#include <boost/mpl/vector.hpp> 


using namespace boost::mpl; 
template <int i> 
struct multiply_scalar 
{ 
    template<typename T> struct apply 
    { 
     typedef int_<(T::value * i)> type; 
    }; 
}; 

typedef vector<int_<3>, int_<4> > my_vec; 
typedef transform< my_vec, multiply_scalar<2> >::type my_vec_2; 

typedef vector<int_<6>, int_<8> > my_vec_3; 

BOOST_MPL_ASSERT((boost::mpl::equal< my_vec_2, my_vec_3 >)); 
+0

非常感谢您的回答。 :) – tgmath 2014-11-01 13:46:49