On Thu, Nov 24, 2011 at 5:25 AM, Allan Nielsen <a@awn.dk> wrote:
Hi

I'm new to the boost::mpl library, and have some "beginners-problems"

template < typename F >
struct A {
   typedef boost::function_types::parameter_types<F> P;
   typedef typename boost::function_types::result_type<F>::type R;

   typedef typename boost::mpl::if_< boost::is_same< R, void >,
                                     boost::function< void ( void ) > ,
                                     boost::function< void ( R ) > >::type TTT;
   A() {
   }
};

int main(int argc, const char *argv[])
{
   A<int(int, float)>  ok; // working
   A<void(int, float)> compile_error; // non-working

   return 0;
}



xxx.cxx: In instantiation of ‘A<void(int, float)>’:
xxx.cxx:108:25:   instantiated from here
xxx.cxx:100:77: error: invalid parameter type
‘boost::mpl::aux::wrapped_type<boost::mpl::aux::type_wrapper<void>
>::type’
xxx.cxx:100:77: error: in declaration ‘A<F>::TTT’


What is the problem here, and how can I solve it.

To my understanding only the selected part of mpl::if_ should be
evaluated by the compiler....

I believe Max Vasin's conclusion is correct.  To be explicit, you're still forming the function type "void ( R )", regardless of whether R is void or not, and (I'm guessing here) the compiler's not cool with that if R is void.  The easier replacement for your mpl::if_ metaexpression might just be to specialize a helper struct:

template< class R > struct helper { typedef void type ( R ); };
template<> struct helper< void > { typedef void type ( ); };

HTH,

- Jeff