Q:

conditional compilation of void argument member method using enable_if

.
#include <iostream>
#include <type_traits>

using namespace std;

template<typename T>
struct MyClass{

  void hello( void) {
    hello(std::is_same<T,bool>());
  }

   void hello(std::true_type){
     cout<<"hello only for bools"<<endl;
   }

};

int main(int argc, char** argv){

  MyClass<bool> myclass1;
  myclass1.hello();

  MyClass<float> myclass2;
  //myclass2.hello(); //throws error as it should

  return 0;
}

I wrote the above code after reading enable_if method specialization. I want the hello() method to exist only if template argument is bool and it works. However I am running into problems when I am trying to solve the same problem using enable_if. I have the following code. Any help is appreciated. If enable_if is not appropriate for this job, what is generally used?
#include <iostream>
#include <type_traits>

using namespace std;

template<typename T>
struct MyClass{

  typename std::enable_if<std::is_same<T,bool>::value, void>::type
  hello(void)
  {
    cout<<"hello only for bools"<<endl;
  }
};

int main(int argc, char** argv){

  MyClass<bool> myclass1;
  myclass1.hello();

  MyClass<float> myclass2;// compilation error. Don't know how to solve
  //myclass2.hello(); //I want only this line to cause compilation error

  return 0;
}

EDIT: I found the solution to my question in jpihl's answer at std::enable_if to conditionally compile a member function. But could anyone explain why the above doesn't work?
#include <iostream>
#include <type_traits>

using namespace std;

template<typename T>
struct MyClass{

  template<class Q = T>
  typename std::enable_if<std::is_same<Q, bool>::value, void>::type hello()
  {
    cout<<"hello only for bools"<<endl;
  }

};

int main(int argc, char** argv){

  MyClass<bool> myclass1;
  myclass1.hello();

  MyClass<float> myclass2;// throws errow. Don't know how to solve
  myclass2.hello(); //

  return 0;
}

A:

Your first attempt with enable_if does not work because SFINAE applies in overload resolution
of function (or member function) templates, where it will eliminate
a specialization of the function template from the overload set when that
specialization cannot compile.
The member hello, in your first attempt, is not a member function template.
It has no template parameters. It is simply a member function of a class template.
Its return type is formulated by an enable_if expression that
will provoke compilation failure if the class template parameter T is not
instantiated as bool. This doesn't make the member function itself into a template.
SFINAE has no application. Once you declare MyClass<float> myclass2, the
specialization of MyClass<T> and all its members is completely determined.
The member function hello of that specialization must be instantiated,
and with T = float the attempt to do so must fail to compile. 
In the second, successful attempt, hello is a member function template (of
a class template). It has a template parameter, Q, which by default is = T.
So SFINAE applies and you can leverage it with enable_if in the intended manner.
You may declare MyClass<float> myclass2 without error, because doing so
does not force any instantiation of the template member MyClass<float>::hello<Q> 
Since you have written only one overload of hello, there is only one specialization
of the member function template for any choice of Q. When Q = bool, that 
single specialization survives and myclass1.hello() will
compile. When Q != bool, SFINAE eliminates the that single specialization
and myclass2.hello() does not compile.
To appeciate vividly how SFINAE in the second case is operating at instantation of
the member function template, consider that:
  MyClass<float> myclass2;
  myclass2.hello<bool>();

is fine; while on the other hand:
  MyClass<bool> myclass1;
  myclass1.hello<float>();

does not compile.
Here is documentation of SFINAE

