
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