$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
From: Steven Watanabe (watanabesj_at_[hidden])
Date: 2008-06-19 18:56:11
AMDG
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.
Yuck.
In Christ,
Steven Watanabe