title: C++: Trying to encapsulate std::enable_if in class
body: <p>I was just using SFINAE to select function templates when I had the glorious idea to encapsulate <code>std::enable_if</code> in a struct like this</p>
  
  <pre><code>template&lt;typename T, typename U&gt;
  struct EnableWhenEqual
  {
      typedef typename std::enable_if&lt;std::is_same&lt;T, U&gt;::value&gt;::type type;
  };
  </code></pre>
  
  <p>and then use it, for example, like this</p>
  
  <pre><code>template&lt;typename T, typename U, typename Enable = EnableWhenEqual&lt;T,U&gt;::type &gt;
  void foo(T&amp;&amp; t, U&amp;&amp; u)
  {
      if (std::is_same&lt;T,U&gt;::value)
          std::cout &lt;&lt; "OK, overload allowed." &lt;&lt; std::endl;
      else
          std::cout &lt;&lt; "Bad. Should not compile!" &lt;&lt; std::endl;
  }
  </code></pre>
  
  <p>However, this doesn't work, as one sees by invoking</p>
  
  <pre><code>foo(1,1);     //prints "OK, overload allowed"
  foo(1,2.0);   //prints "Bad, should not compile", but obviously does
  </code></pre>
  
  <p>On the other hand, by trying to create</p>
  
  <pre><code>EnableWhenEqual&lt;int,int&gt;();      //compiles
  EnableWhenEqual&lt;int,double&gt;();   //does not compile because type does not exist
  </code></pre>
  
  <p>one obtains a compiler error ("type is not a member of std::enable_if").</p>
  
  <p>What is the reason for this behaviour? I'm asking because from my little SFINAE knowledge I would have thought that an error in the type-deduction leads to exclusion of the overload ... ?</p>
  
  <hr>
  
  <p>For completeness, the above problem can be solved using template aliasing</p>
  
  <pre><code>template &lt;typename T, typename U&gt;
  using EnableWhenEqual = typename std::enable_if&lt;std::is_same&lt;T,U&gt;::value&gt;::type;
  </code></pre>
  
  <p>Is there also an alternative using a struct instead of a template alias?</p>
  
  <p><strong>EDIT:</strong> Here I mean an implementation which solves the general problem. For example, this here</p>
  
  <pre><code>template&lt;typename T, typename U, bool B, typename C=void&gt;
  struct EnableWhenEqual {};
  
  template&lt;typename T, typename U, typename C&gt;
  struct EnableWhenEqual&lt;T,U,std::is_same&lt;T,U&gt;::value&gt;
  {
      typedef typename C type;
  };
  </code></pre>
  
  <p>don't works for me because the partial specialization needs a simple identifier. If it would, one could replace <code>std::is_same</code> by general structs <code>Condition&lt;T,U&gt;</code>. Any alternatives?</p>