[type_traits?] enable_if an overload for a function exists

I want to enable a function templated on a type T if a function it relies on overloaded on that type. All I know is that this compiles for types I want to enable on and fails to compile for types I want to disable on. static float (*const func ) ( float , float ) = std::atan2; // compiles static int (*const func ) ( int , int ) = std::atan2; // fails to compile Ideally I think I'd like to do something like: template< typename T > typename enable_if< is_overloaded< T ( T ), std::asin > >::type some_function( T x ) { std::cout << std::asin(x); } I'm not even sure if I really need this or not. The best I've come up with has problems with the compiler crashing in some cases. It is illustrated by the following toy example (only tested with vs2005). namespace method { namespace detail { template< typename Signature, Signature* signature, typename T = void > struct enable_if_overloaded { typedef T type; }; } // end namespace detail template< typename T > inline typename detail::enable_if_overloaded<T (T), std::asin, radians<T>
::type my_asin( T x ) { return radians<T>( std::asin( x ) ); }
template< typename T > inline typename boost::enable_if< boost::is_integral<T>, radians<float> >::type my_asin( T x ) { return my_asin( static_cast<float>(x) ); } } // end namespace method void test() { method::my_asin( 1.1f ); method::my_asin( 1 ); } Thanks, Michael Marcin

On Thu, 19 Apr 2007 23:10:31 +0200, Michael Marcin <mmarcin@method-solutions.com> wrote:
I want to enable a function templated on a type T if a function it relies on overloaded on that type.
.....
template< typename T > inline typename detail::enable_if_overloaded< T (T), std::asin, radians<T>
::type my_asin( T x ) { return radians<T>( std::asin( x ) ); }
I tried your code on gcc 4.1.1 and compiler crashes, too. I found that if the function symbol passed as argument for Signature* template parameter isn't overloaded, that is there is only one signature bounded to the function name, your code works correctly. IMO the problem is : if a function is overloaded what is its type ? example: float std::asin(float ) long double std::asin(long double ) tipeof( std::asin ) is "float (float )" or "long double (long double )" ? I don't know what the standard says about. Anyway, I don't understand why vc and gcc crash. Marco -- Using Opera's revolutionary e-mail client: http://www.opera.com/mail/

AMDG Marco <mrcekets <at> gmail.com> writes:
On Thu, 19 Apr 2007 23:10:31 +0200, Michael Marcin <mmarcin <at> method-solutions.com> wrote:
I want to enable a function templated on a type T if a function it relies on overloaded on that type.
How about? template<class T> yes is_overloaded(T); template<class T> no is_overloaded(...); #define BOOST_IS_OVERLOADED(t, name) \ (sizeof(is_overloaded<t>(name)) == sizeof(yes)) No that doesn't work either. If there are multiple functions the compiler won't know which one to pass to is_overloaded(...) Um. Since you are looking for the exact signature (untested): namespace detail { namespace is_overloaded_adl_barrier { typedef chr no; struct yes { no dummy[2]; }; struct no_overload {}; yes is_overloaded_impl(...); no is_overloaded_impl(const no_overload&); struct any_conversion { template<class T> any_conversion(const T&); }; no_overload atan2(any_conversion, any_conversion); template<class T> T make(); template<class T> struct has_atan2 : mpl::bool_< sizeof(is_overloaded_impl(atan2(make<T>(), make<T>()))) == sizeof(yes)
{}; } using is_overloaded_adl_barrier::has_atan2; } In Christ, Steven Watanabe

On Fri, 20 Apr 2007 04:26:04 +0200, Steven Watanabe <steven@providere-consulting.com> wrote:
Um. Since you are looking for the exact signature (untested):
namespace detail {
namespace is_overloaded_adl_barrier {
typedef chr no; struct yes { no dummy[2]; };
struct no_overload {};
yes is_overloaded_impl(...); no is_overloaded_impl(const no_overload&); struct any_conversion { template<class T> any_conversion(const T&); };
no_overload atan2(any_conversion, any_conversion);
template<class T> T make();
template<class T> struct has_atan2 : mpl::bool_< sizeof(is_overloaded_impl(atan2(make<T>(), make<T>()))) == sizeof(yes)
{};
}
using is_overloaded_adl_barrier::has_atan2;
}
In Christ, Steven Watanabe
Nice! :-) I tested it and it seems to work but it's necessary to add "using std::atan2" inside is_overloaded_adl_barrier namespace else only "no_overload atan2(any_conversion, any_conversion)" is seen. Marco -- Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
participants (3)
-
Marco
-
Michael Marcin
-
Steven Watanabe