SFINAE: determine if a class has a free function

Is there a way, using SFINAE, to determine if a free function is overloaded for a given class?

Basically, Ive got the following solution:

struct has_no_f { }; struct has_f { }; void f(has_f const& x) { } template <typename T> enable_if<has_function<T, f>::value, int>::type call(T const&) { std::cout << "has f" << std::endl; } template <typename T> disable_if<has_function<T, f>::value, int>::type call(T const&) { std::cout << "has no f" << std::endl; } int main() { call(has_no_f()); // "has no f" call(has_f()); // "has f" } 

Just call overloading does not work, because in fact there are many types foo and bar , and the call function does not know about them (basically call is inside a, and users provide their own types).

I cannot use C ++ 0x, and I need a working solution for all modern compilers.

Note: the solution for a similar question , unfortunately, does not work here.

+6
c ++ templates sfinae
source share
2 answers
 #include <iostream> #include <vector> #include <algorithm> #include <utility> #include <functional> #include <type_traits> struct X {}; struct Y {}; __int8 f(X x) { return 0; } __int16 f(...) { return 0; } template <typename T> typename std::enable_if<sizeof(f(T())) == sizeof(__int8), int>::type call(T const& t) { std::cout << "In call with f available"; f(t); return 0; } template <typename T> typename std::enable_if<sizeof(f(T())) == sizeof(__int16), int>::type call(T const& t) { std::cout << "In call without f available"; return 0; } int main() { Y y; X x; call(y); call(x); } 

Fast modification of return types f () gives the traditional SFINAE solution.

+3
source share

If boost enabled, the following code may suit your purpose:

 #include <boost/type_traits.hpp> #include <boost/utility/enable_if.hpp> using namespace boost; // user code struct A {}; static void f( A const& ) {} struct B {}; // code for has_f static void f(...); // this function has to be a free standing one template< class T > struct has_f { template< class U > static char deduce( U(&)( T const& ) ); template< class U, class V > static typename disable_if_c< is_same< V, T >::value, char(&)[2] >::type deduce( U(&)( V const& ) ); static char (&deduce( ... ))[2]; static bool const value = (1 == sizeof deduce( f )); }; int main() { cout<< has_f<A>::value <<endl; cout<< has_f<B>::value <<endl; } 

However, there are serious limitations.
The code assumes that all user-defined functions are signed ( T const& ) , therefore ( T ) not allowed.
The void f(...) function in the above seems to be a free function.
If the compiler provides a two-phase search, as usual, all user functions should appear before the class has_f template definition.
Honestly, I'm not sure about the usefulness of the code, but in any case, I hope this helps.

+3
source share

All Articles