Boost logo

Boost Users :

From: Steven Watanabe (watanabesj_at_[hidden])
Date: 2008-06-19 18:56:11


Martin Apel wrote:
> I stumbled across something very strange related to
> boost::mpl::for_each and numbered vectors and sets (as opposed to the
> variadic forms). The program below contains a typelist with 21 (i.e.
> more than BOOST_MPL_LIMIT_SET_SIZE) classes. This typelist is
> converted to a typelist containing pointers to those classes. Finally
> the main program calls for_each with that typelist to print the names
> of the types. This works without problems on Linux and Windows. But now:
> If you remove the include "boost/mpl/vector/vector30.hpp" everything
> still compiles fine without warnings under both operating systems. On
> Linux everything continues to work, whereas under Windows nothing is
> printed anymore.

I don't think that it should compile on windows. I assume that you are
using msvc
on Windows and gcc on Linux?

> for_each does not loop through the typelist for an unknown reason.
> Everything works again, when reducing the number of classes to 20 (and
> adjusting the include to set20.hpp).
> From my understanding BOOST_MPL_LIMIT_SET_SIZE and its brothers and
> sisters should not have any impact on numbered sequences, only on
> variadic ones. But still it looks as if something very strange is
> happening here.

Here's the result of the transform is on msvc 9.0
boost::mpl::vector21<C21 *,C20 *,C19 *,C18 *,C17 *,C16 *,C15 *,C14 *,C13
*,C12 *,C11 *,C10 *,C9 *,C8 *,C7 *,C6 *,C5 *,C4 *,C3 *,C2 *,C1 *>

Without <boost/mpl/vector/vector30.hpp> the result is
boost::mpl::push_back<boost::mpl::vector20<C21 *,C20 *,C19 *,C18 *,C17
*,C16 *,C15 *,C14 *,C13 *,C12 *,C11 *,C10 *,C9 *,C8 *,C7 *,C6 *,C5 *,C4
*,C3 *,C2 *>,C1 *>

The reason? On compilers without typeof, including msvc, push_back on a
vector0 gives
a vector1, push_back on a vector1 gives a vector2, and so on. The
unnumbered form
is specialized for every possible number of arguments and inherits from
the appropriate
numbered form.

Now for the strange part--when an mpl lambda expression is evaluated it
checks to see
whether the result of substituting placeholders is a metafunction, in
other words it looks for
a nested typedef ::type. If this is present, then it will return that
typedef, otherwise, it
will return type type unchanged. For example the expressions
boost::mpl::apply<std::vector<_1>, int>::type evaluates to std::vector<int>.
Now, if you don't #include <boost/mpl/vector/vector30.hpp>, there will be
no specialization of push_back for vector20, thus mpl::lambda will think
that the push_back is not a metafunction and return it unchanged.

Finally, when mpl::begin and mpl::end are called on a type that is not
an MPL sequence, they return mpl::void_. Since begin and end return
the same type, for_each decides that it is dealing with an empty sequence.


In Christ,
Steven Watanabe

Boost-users list run by williamkempf at, kalb at, bjorn.karlsson at, gregod at, wekempf at