diff options
Diffstat (limited to 'boost/functional/forward_adapter.hpp')
-rw-r--r-- | boost/functional/forward_adapter.hpp | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/boost/functional/forward_adapter.hpp b/boost/functional/forward_adapter.hpp index 796abd2bc4..6023fc2ae5 100644 --- a/boost/functional/forward_adapter.hpp +++ b/boost/functional/forward_adapter.hpp @@ -144,8 +144,30 @@ namespace boost : boost::result_of< BOOST_DEDUCED_TYPENAME c<Self>::t() > { }; - template< class MD, class F, class FC > - struct forward_adapter_impl<MD,F,FC,0,0> + // 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 <typename T, typename R = void> + 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 <typename T> struct never_instantiate {}; + template <typename T> + typename never_instantiate<T>::type operator()(T) const {} + }; + + template< class MD, class F, class FC> + struct forward_adapter_impl_zero<MD, F, FC, + typename forward_adapter_sfinae<typename boost::result_of< FC() >::type>::type> { inline typename boost::result_of< FC() >::type operator()() const @@ -158,6 +180,13 @@ namespace boost { return static_cast<MD*>(this)->target_function()(); } + }; + + template< class MD, class F, class FC > + struct forward_adapter_impl<MD,F,FC,0,0> + : forward_adapter_impl_zero<MD,F,FC> + { + using forward_adapter_impl_zero<MD,F,FC>::operator(); // closing brace gets generated by preprocessing code, below |