Boost logo

Boost :

Subject: Re: [boost] boost::mpl::for_each and value_initialized
From: Patrick Mihelich (patrick.mihelich_at_[hidden])
Date: 2010-01-26 16:42:21

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.


#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) {}

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_at_[hidden]> wrote:

> Anyway, I wouldn't mind if the memset call in utility/value_init.hpp
>>> would become conditional, for example as follows:
>>> 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
> Scientific programmer at LKEB, Leiden University Medical Center
> _______________________________________________
> Unsubscribe & other changes:

Boost list run by bdawes at, gregod at, cpdaniel at, john at