I want to multiply each element in an mpl::vector
by an int
.
First, a metafunction to multiply an int_
with an int
.
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
Instead of simply writing
boost::mpl::vector<>
boost::mpl::vector<T>
boost::mpl::vector<T, U>
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
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
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.
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 > ));