
If I understand correctly, the only purpose of the initialized argument is to select the correct template method? Recently I had another problem with mpl::for_each, in that I was trying to use it to iterate over a sequence of tag types. For my application it was most convenient to leave these tag types incomplete (macros could declare them more than once), using them only for template logic. Of course mpl::for_each then failed because it was trying to instantiate incomplete types. I guess that David Abrahams' trick of transforming the sequence to wrap<T> could have worked (it didn't occur to me), but it feels kludgy. I prefer to minimize compile times and avoid the value_initialized business. My solution was to write "for_each_type", which is just mpl::for_each without the value_initialized argument. Maybe this should also exist in the MPL? It seems both approaches have drawbacks. mpl::for_each does not work for some types (without sequence transformation), and it creates an instance that normally is not used. "for_each_type" does not work for normal function objects - though I am not convinced that is a typical use case. For anyone who's interested, I've appended "for_each_type" below. This is a "clean" implementation, that assumes a well-behaved compiler. -Patrick #include <boost/mpl/is_sequence.hpp> #include <boost/mpl/begin_end.hpp> #include <boost/mpl/next_prior.hpp> #include <boost/mpl/deref.hpp> #include <boost/mpl/assert.hpp> #include <boost/mpl/aux_/unwrap.hpp> #include <boost/type_traits/is_same.hpp> template< bool done = true > struct for_each_type_impl { template<typename Iterator, typename LastIterator, typename F> static void execute(F) {} }; template<> struct for_each_type_impl<false> { template<typename Iterator, typename LastIterator, typename F> static void execute(F f) { typedef typename boost::mpl::deref<Iterator>::type arg; boost::mpl::aux::unwrap(f, 0).template operator()<arg>(); typedef typename boost::mpl::next<Iterator>::type iter; for_each_type_impl<boost::is_same<iter, LastIterator>::value> ::template execute<iter, LastIterator, F>(f); } }; template<typename Sequence, typename F> void for_each_type(F f) { BOOST_MPL_ASSERT(( boost::mpl::is_sequence<Sequence> )); typedef typename boost::mpl::begin<Sequence>::type first; typedef typename boost::mpl::end<Sequence>::type last; for_each_type_impl< boost::is_same<first, last>::value >::template execute<first, last, F>(f); } On Tue, Jan 26, 2010 at 7:27 AM, Niels Dekker - address until 2010-10-10 < niels_address_until_2010-10-10@xs4all.nl> wrote:
Anyway, I wouldn't mind if the memset call in utility/value_init.hpp
would become conditional, for example as follows:
#ifdef BOOST_VALUE_INITIALIZATION_NEEDS_MEMSET std::memset(&x, 0, sizeof(x)); #endif
Fernando (the author of value_init) mailed me that it's okay to him if I add an #ifdef like that to utility/value_init.hpp. Still I think it would be useful to have the issue officially reported. Aleksey, were you already planning to open a ticket on this issue? If so, please do! And please feel free to assign the ticket to niels_dekker :-)
Of course, <boost/config/compiler/...> also needs to have BOOST_VALUE_INITIALIZATION_NEEDS_MEMSET added to various compiler versions:
MSVC (all versions)
Borland/Codegear build < 12.0.3140.16150 Sun (possibly all versions, I don't know exactly) GCC < 4.4.0
What do you think? And would it be okay to you to have such a macro,
BOOST_VALUE_INITIALIZATION_NEEDS_MEMSET, defined in boost/config/compiler/, for those specific compiler versions?
Aleksey Gurtovoy wrote:
Sounds good to me. John?
Hope it's okay to John as well.
Kind regards,
Niels -- Niels Dekker http://www.xs4all.nl/~nd/dekkerware<http://www.xs4all.nl/%7End/dekkerware> Scientific programmer at LKEB, Leiden University Medical Center
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost