我想将mpl::vector
中的每个元素乘以int
。
首先,将int_
与int
相乘的元函数。
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>>
?我拿错了吗?可能没有以正确的方式应用元函数或变换。
答案 0 :(得分:6)
主要是因为MPL的编写者C ++ 03中的一些实现问题 不得不使用非显而易见的技术来表示序列,其中之一就是 类似
的用法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
因此,documentation
对于boost::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,否则这可能对你没有帮助
你不会就此问题提出问题;-),所以基本上它意味着它会回来
一种类似boost::mpl::vector
的新类型,除了它的实际类型
就像我上面展示的一样。特别是,这种类型保证是一个模型
Forward Sequence概念。
当您使用boost::is_same<T, U>
时,您实际上是在询问T
和U
是正好相同的类型。你现在应该清楚地看到为什么这不是什么
你真的想要。相反,您希望对这些进行某种深度比较
两个序列,都代表向量。要检查两个转发
序列相等,您必须使用boost::mpl::equal
算法代替。以下内容适用:
#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 > ));