diff --git a/include/boost/functional/forward_adapter.hpp b/include/boost/functional/forward_adapter.hpp index 796abd2..6023fc2 100644 --- a/include/boost/functional/forward_adapter.hpp +++ b/include/boost/functional/forward_adapter.hpp @@ -144,8 +144,30 @@ namespace boost : boost::result_of< BOOST_DEDUCED_TYPENAME c::t() > { }; - template< class MD, class F, class FC > - struct forward_adapter_impl + // WHen operator()() doesn't have any parameters, it can't + // be templatized and can't use SFINAE, so intead use class + // template parameter SFINAE to decide whether to instantiate it. + + template + struct forward_adapter_sfinae + { + typedef T type; + }; + + // This is the fallback for when there isn't an operator()(), + // need to create an operator() that will never instantiate + // so that using parent::operator() will work okay. + template< class MD, class F, class FC, class Enable = void> + struct forward_adapter_impl_zero + { + template struct never_instantiate {}; + template + typename never_instantiate::type operator()(T) const {} + }; + + template< class MD, class F, class FC> + struct forward_adapter_impl_zero::type>::type> { inline typename boost::result_of< FC() >::type operator()() const @@ -158,6 +180,13 @@ namespace boost { return static_cast(this)->target_function()(); } + }; + + template< class MD, class F, class FC > + struct forward_adapter_impl + : forward_adapter_impl_zero + { + using forward_adapter_impl_zero::operator(); // closing brace gets generated by preprocessing code, below diff --git a/include/boost/functional/lightweight_forward_adapter.hpp b/include/boost/functional/lightweight_forward_adapter.hpp index 637aa9e..2706d29 100644 --- a/include/boost/functional/lightweight_forward_adapter.hpp +++ b/include/boost/functional/lightweight_forward_adapter.hpp @@ -149,8 +149,31 @@ namespace boost : boost::result_of< BOOST_DEDUCED_TYPENAME c::t() > { }; - template< class MD, class F, class FC > - struct lightweight_forward_adapter_impl + // When operator() doesn't have any parameters, it can't + // be templatized and can't use SFINAE, so intead use class + // template parameter SFINAE to decide whether to instantiate it. + + template + struct lightweight_forward_adapter_sfinae + { + typedef T type; + }; + + // This is the fallback for when there isn't an operator()(), + // need to create an operator() that will never instantiate + // so that using parent::operator() will work okay. + template< class MD, class F, class FC, class Enable = void> + struct lightweight_forward_adapter_impl_zero + : lightweight_forward_adapter_result + { + template struct never_instantiate {}; + template + typename never_instantiate::type operator()(T) const {} + }; + + template< class MD, class F, class FC> + struct lightweight_forward_adapter_impl_zero::type>::type> : lightweight_forward_adapter_result { inline typename boost::result_of< FC() >::type @@ -166,6 +189,12 @@ namespace boost } }; + template< class MD, class F, class FC > + struct lightweight_forward_adapter_impl + : lightweight_forward_adapter_impl_zero + { + }; + # define BOOST_PP_FILENAME_1 \ # define BOOST_PP_ITERATION_LIMITS \