Implementation of has_member_function From https://stackoverflow.com/a/257382/6949852
I learned how to check whether a member function exists, then I re-write it to standardize the codes: 

Now the codes become: 

#include &lt;type_traits&gt;
#include &lt;iostream&gt;

struct A  //has hello
{
  void hello() {}
};

struct B {}; //no hello

template&lt;typename T&gt;
struct has_hello
{
private:
  using yes = char;
  using no = long;
  template&lt;typename C&gt;
  static yes has(decltype(&amp;C::hello));
  template&lt;typename C&gt;
  static no has(...);
public:
  enum name : bool {value = std::is_same&lt;decltype(has&lt;T&gt;(nullptr)), yes&gt;::value};
};

int main()
{
  std::cout &lt;&lt; static_cast&lt;std::underlying_type&lt;has_hello&lt;A&gt;::name&gt;::type&gt;(has_hello&lt;A&gt;::value) &lt;&lt; std::endl;
  std::cout &lt;&lt; static_cast&lt;std::underlying_type&lt;has_hello&lt;B&gt;::name&gt;::type&gt;(has_hello&lt;B&gt;::value) &lt;&lt; std::endl;
}


Compared to original codes:


0 -> nullptr
enum -> enum name : type
sizeof -> is_same
typeof -> decltype
Old technique

The version you're using relies on overload resolution. The current form of detection idiom relies on SFINAE. IIRC SFINAE didn't exist pre-C++11.(Thanks to @JDlugosz) 

Code Review


Inherit from std::true_type and std::false_type

That will spare a lot of boilerplate, and incorporates with tag dispatch quite well. It might not be directly usable in your case without some indirection and hiding into namespace detail.
Don't use enum as a member where static constexpr bool will do

Even though with freestanding values it is a different story due to linkage. bool will just bring less surprises.
Provide xxx_v value aliases


Somewhat modern approach

Lets take somewhat more interesting example. 


  Identify if value of type Element can be push_backed into container of type Container.


Today, it is suggested to first "carve out" the operation itself into an alias:

template &lt;typename Container, typename Element&gt;
using pushback_t = decltype(std::declval&lt;Container&gt;().push_back(std::declval&lt;Element&gt;()));


Then, std::void_t is used:

template &lt;typename Container, typename Element, typename = std::void_t&lt;&gt;&gt;
struct has_pushback : std::false_type{};

template &lt;typename Container, typename Element&gt;
struct has_pushback&lt;Container, Element, std::void_t&lt;pushback_t&lt;Container, Element&gt;&gt;&gt;:
                        std::true_type{};


And then _v value alias is provided:

template &lt;typename Container, typename Element&gt;
inline constexpr bool has_pushback_v = has_pushback&lt;Container, Element&gt;::value;


Demo.

Shameless self PR: if you're a bit confused about how SFINAE works in the new version, I recommend reading this question which I've asked in the past.

Better upgrade path

When std::is_detected will arrive, one can easily put something like this (provided a copy the operation alias from above):

template &lt;typename Container, typename Element&gt;
struct has_pushback : std::is_detected&lt;pushback_t, Container, Element&gt;
{};


That will spare even more boilerplate. See comments for already existing implementations.