Boost logo

Boost Users :

From: Edd Dawson (edd_at_[hidden])
Date: 2006-08-21 13:58:12


Hi Dave,

Thanks for your reply.

David Abrahams wrote:
> David Abrahams <dave_at_[hidden]> writes:
>
>> Edd Dawson <edd_at_[hidden]> writes:
>>
>>> Hello all,
>>>
>>> I have the following:
>>>
>>> template<typename T>
>>> void f() { /* ... */ }
>>>
>>> typedef boost::mpl::vector<int, long, double> my_vec;
>>>
>>> I'm looking for a way to call f<T>() for all types T in my_vec. I initially
>>> hoped that either an mpl algorithm or fusion::for_each might be able to
>>> accomplish this for me, but after reading through their docs this doesn't appear
>>> to be the case.
>> struct call_f
>> {
>> template <class Wrapper>
>> void operator()(Wrapper)
> Sorry, it's missing a "const" right here--^^^^
>> {
>> f<typename Wrapper::type>();
>> }
>> };
>>
>> mpl::for_each<my_vec, mpl::identity<_> >(call_f());
>

I didn't find this in the docs. Is it meant to be there?

Unfortunately, that didn't quite work for me, anyway. A requirement of for_each
(according to my MSVC 8 diagnostics) is that each type in the sequence must be
default constructible.

The (near) exact code I'm trying to compile is:

     struct register_cage
     {
         template<typename wrapper>
         void operator()(wrapper) const
         {
             // ...
         }
     };

     struct null_type { };

     // template<typename T1 = null_type, ..., typename TN = null_type>
     template<
         BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_MPL_LIMIT_VECTOR_SIZE,
typename T, null_type)
>
     struct catch_exceptions
     {
         typedef typename boost::mpl::vector<
             BOOST_PP_ENUM_PARAMS(BOOST_MPL_LIMIT_VECTOR_SIZE, T)
>::type exception_types;

         catch_exceptions()
         {
             using namespace boost::mpl;

             typedef boost::mpl::_1 my1;
             typedef boost::mpl::_2 my2;

             // Remove all null_type entries and then sort the remaining ones,
             // most derived to front.
             typedef remove_if<
                 exception_types,
                 boost::is_same<_, null_type>
>::type unique_exception_types;
                
             typedef sort<
                 unique_exception_types,
                 boost::is_base_of<my2, my1>
>::type sorted_exception_types;
                                
             for_each<sorted_exception_types, identity<_> >(register_cage());
         }
     };

     // Elsewhere, in 'client' code

     catch_exceptions<std::exception, std::runtime_error>();

The most appropriate part of the (long) compiler error is:

1>c:\development\boost\include\boost-1_33_1\boost\utility\value_init.hpp(34) :
error C2512: 'std::runtime_error' : no appropriate default constructor available

1>
c:\development\boost\include\boost-1_33_1\boost\utility\value_init.hpp(34) :
while compiling class template member function
'boost::vinit_detail::non_const_T_base<T>::non_const_T_base(void)'

Assuming that I have interpreted the compiler errors correctly, is this
default-constructible requirement really necessary? I can do the task using the
trick I listed in my original post so I would expect a library of this kind to
be able to.

Kind regards,

Edd


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net