Problems using mpl::if_ and function_types::result_type

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.... Regards Allan W. Nielsen

Hello, Allan, although I do not know the answer I post some results that I have got. Your problem has nothing to do with either MPL or function_types. First of all declaring function to take a void parameter is deprecated, the type `void (void)' is in fact `void ()'. When you declare a function type void (R) where R depends on a template parameter compiler expects to get an unary function type but when R is void the function is nullary (and turning an unary function into nullary seem to be forbidden). This minimal example demonstates the issue: template <typename F> struct A { typedef void type(F); }; int main(int argc, const char *argv[]) { A<int> ok; A<void> fail; } What you need is partial template specialization. And I will wait for the expert answer. -- WBR, Max Vasin.

Hi I might have simplified the problem too much... If my template argument is: F: < int(double) > Then I needed to define the type: boost::function< void(bool, int) > If my template argument is: F: < void(double) > Then I needed to define the type: boost::function< void(bool) > But I actually got a pretty reply on stackoverflow, where Partial specializatio is suggested as an solution: http://stackoverflow.com/questions/8258267/problems-using-mplif-boostfunctio... Thanks for the input any way Regards Allan W. Nielsen On Thu, Nov 24, 2011 at 3:26 PM, Max Vasin <max.vasin@gmail.com> wrote:
Hello, Allan, although I do not know the answer I post some results that I have got. Your problem has nothing to do with either MPL or function_types. First of all declaring function to take a void parameter is deprecated, the type `void (void)' is in fact `void ()'. When you declare a function type void (R) where R depends on a template parameter compiler expects to get an unary function type but when R is void the function is nullary (and turning an unary function into nullary seem to be forbidden). This minimal example demonstates the issue:
template <typename F> struct A { typedef void type(F); };
int main(int argc, const char *argv[]) { A<int> ok; A<void> fail; }
What you need is partial template specialization. And I will wait for the expert answer.
-- WBR, Max Vasin. _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

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
participants (3)
-
Allan Nielsen
-
Jeffrey Lee Hellrung, Jr.
-
Max Vasin