用自己的功能转换mpl向量 [英] Transforming mpl vector with own function

查看:66
本文介绍了用自己的功能转换mpl向量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将mpl::vector中的每个元素乘以int. 首先,使用元函数将int_int相乘.

I want to multiply each element in an mpl::vector by an int. First, a metafunction to multiply an int_ with an 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>>?我错了吗?元功能或变换可能没有正确应用.

Why isn't the resulting vector simply a vector<int_<6>, int_<8>>? Am I holding it wrong? Probably the metafunction or the transform is not applied in the right way.

推荐答案

主要是由于C ++ 03中的某些实现问题,MPL的编写者 必须使用非显而易见的技术来表示序列,其中之一是 像

Mainly because of some implementation issues in C++03, the writers of the MPL had to use non-obvious techniques for representing sequences, one of which is the usage of types like

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及更高版本中使用可变参数模板一样.另一种技术 是在向量中插入内容时创建某种反向链接列表, 在您的示例中正在查看的内容:

as one would do with variadic templates in C++11 and beyond. Another technique is to create some kind of reverse linked list when you insert stuff in a vector, which is what you're looking at in your example:

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

因此,文档 对于boost::mpl::transform并没有确切地指定 什么是boost::mpl::transform<s,op,in>::type类型. 实际上,它仅保证它的类型等于

Because of this, the documentation for boost::mpl::transform does not specify exactly what is the type of boost::mpl::transform<s,op,in>::type. Actually, it only guarantees that it's a type equivalent to

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的新类型,但其实际类型可能会 就像我上面显示的那样.特别是,这种类型可以保证是一个模型 转发序列概念的说明.

This probably does not help you unless you already know the MPL well enough that you don't ask questions on SO about it ;-), so basically it means that it returns a new type that's like a boost::mpl::vector, except for its actual type which may be anything like I showed above. In particular, this type is guaranteed to be a model of the Forward Sequence concept.

使用boost::is_same<T, U>时,实际上是在询问TU精确地相同的类型.您现在应该清楚地知道为什么这不是事实 你真正想要的.相反,您想对它们进行比较 两个序列,都代表向量.检查是否两个转发 序列相等,必须使用 boost::mpl::equal 算法代替.以下将起作用:

When you use boost::is_same<T, U>, you're actually asking whether T and U are precisely the same types. You should now see clearly why this is not what you actually want. Instead, you want to do some kind of deep comparison of those two sequences, which both represent vectors. To check whether two Forward Sequences are equal, you must use the boost::mpl::equal algorithm instead. The following will work:

#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 > ));

这篇关于用自己的功能转换mpl向量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆