SFINAE: detect if class has free function

独自空忆成欢 提交于 2019-12-03 03:26:28
#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);
}

A quick modification of the return types of f() yields the traditional SFINAE solution.

If boost is allowed, the following code might meet 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 severe restrictions.
The code assumes that all the user functions have the signature ( T const& ), so ( T ) isn't allowed.
The function void f(...) in the above seems to need to be a free standing function.
If the compiler enforces two phase look-up as expected normally, probably all the user functions have to appear before the definition of has_f class template.
Honestly, I'm not confident of the usefulness of the code, but anyway I hope this helps.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!