title: Member function template selection and SFINAE
body: <p>I've been trying to understand the way C++ selects templates. Namely, consider the following code sample:</p>
  
  <pre class="lang-cpp prettyprint-override"><code>template &lt;typename R&gt;
  class Curious
  {
  public:
      template &lt;typename T, typename std::enable_if&lt;std::is_const&lt;T&gt;::value, int&gt;::type = 33&gt;
      void test1() {}
  
      template &lt;typename T, typename std::enable_if&lt;!std::is_const&lt;T&gt;::value, int&gt;::type = 33&gt;
      void test1() {}
  
      template &lt;typename T, typename = typename std::enable_if&lt;std::is_const&lt;T&gt;::value&gt;::type&gt;
      void test2() {}
  
      template &lt;typename T, typename = typename std::enable_if&lt;!std::is_const&lt;T&gt;::value&gt;::type&gt;
      void test2() {}
  
      template &lt;typename std::enable_if&lt;std::is_const&lt;R&gt;::value&gt;::type * = nullptr&gt;
      void test3() {}
  
      template &lt;typename std::enable_if&lt;!std::is_const&lt;R&gt;::value&gt;::type * = nullptr&gt;
      void test3() {}
  
      // works
      template &lt;typename T = void&gt;
      typename std::enable_if&lt;std::is_const&lt;R&gt;::value, T&gt;::type test4() {}
  
      template &lt;typename T = void&gt;
      typename std::enable_if&lt;!std::is_const&lt;R&gt;::value, T&gt;::type test4() {}
  
      // also works
      template &lt;typename T = void, typename std::enable_if&lt;std::is_const&lt;R&gt;::value, T&gt;::type * = nullptr&gt;
      void test5() {}
  
      template &lt;typename T = void, typename std::enable_if&lt;!std::is_const&lt;R&gt;::value, T&gt;::type * = nullptr&gt;
      void test5() {}
  }; // Curious
  </code></pre>
  
  <p>The first two functions (test1) work fine (<strong>why?</strong>):</p>
  
  <pre><code>Curious&lt;int&gt; curious;
  curious.test1&lt;int&gt;();
  curious.test1&lt;const int&gt;();
  </code></pre>
  
  <p>While the rest of them cause compilation errors. 
  Regarding the function test2 the compiler claims I'm trying to create a duplicate:</p>
  
  <pre>error C2535: 'void Curious::test2(void)': member function already defined or declared</pre>
  
  <p><a href="http://en.cppreference.com/w/cpp/types/enable_if" rel="nofollow">Here</a> the documentation says:</p>
  
  <blockquote>
    <p>A common mistake is to declare two function templates that differ only
    in their default template arguments. This is illegal because default
    template arguments are not part of function template's signature, and
    declaring two different function templates with the same signature is
    illegal.</p>
  </blockquote>
  
  <p>So it seems to be the case. However, I don't see that much difference from the first two functions, which also have the default template argument. Thus we have a default type (test2 - doesn't work) against a default value (test1 - works). Is there any rule about it? </p>
  
  <p>In case of test3: <pre>error C2039: 'type': is not a member of 'std::enable_if'</pre>
  Like in the first case this time the member function template has a default non-type parameter, but it depends on the class template parameter. Now SFINAE doesn't skip the wrong one (also not sure why).</p>
  
  <p>In the fourth case SFINAE resolves the template by the return type. But don't these test4 functions have identical signature? As they differ only in the return type.</p>
  
  <p>As far as I understand, in the fifth case adding extra parameter makes test5 signature dependent on the function template parameter, therefore SFINAE kicks in and resolution works.</p>
  
  <p>I'm quite confused about how C++ deals with these templates. Could somebody be so kind to clear these things up?</p>