title: "What happened to my SFINAE" redux: conditional template class members?
body: <p>I'm new to writing template metaprogramming code (vs. just reading it).  So I'm running afoul of some noob issues.  One of which is pretty well summarized by this non-SO post called <a href="http://www.velocityreviews.com/forums/t743535-what-happened-to-my-sfinae.html" rel="nofollow noreferrer">"What happened to my SFINAE?"</a>, which I will C++11-ize as this:</p>
  
  <p><em>(Note: I gave the methods different names only to help with my error diagnosis in this "thought experiment" example.  See <a href="https://stackoverflow.com/a/11532326/211160">@R.MartinhoFernandes's notes</a> on why you wouldn't actually choose this approach in practice for non-overloads.)</em></p>
  
  <pre><code>#include &lt;type_traits&gt;
  
  using namespace std;
  
  template &lt;typename T&gt;
  struct Foo {
      typename enable_if&lt;is_pointer&lt;T&gt;::value, void&gt;::type
      valid_if_pointer(T) const { }
  
      typename disable_if&lt;is_pointer&lt;T&gt;::value, void&gt;::type
      valid_if_not_pointer(T) const { }
  };
  
  int main(int argc, char * argv[])
  {
      int someInt = 1020;
      Foo&lt;int*&gt;().valid_if_pointer(&amp;someInt);    
      Foo&lt;int&gt;().valid_if_not_pointer(304);
  
      return 0;
  }
  </code></pre>
  
  <p>@Alf says what happened to the SFINAE is "It wasn't there in the first place", and gives a suggestion that compiles, but templates the functions instead of the class.  That might be right for some situations, but not all.  <em>(For instance: I'm specifically trying to write a container that can hold types that may or may not be copy-constructible, and I need to flip methods on and off based on that.)</em></p>
  
  <p>As a workaround, I gave this a shot...which appears to work correctly.</p>
  
  <pre><code>#include &lt;type_traits&gt;
  
  using namespace std;
  
  template &lt;typename T&gt;
  struct FooPointerBase {
      void valid_if_pointer(T) const { }
  };
  
  template &lt;typename T&gt;
  struct FooNonPointerBase {
      void valid_if_not_pointer(T) const { }
  };
  
  template &lt;typename T&gt;
  struct Foo : public conditional&lt;
      is_pointer&lt;T&gt;::value, 
      FooPointerBase&lt;T&gt;,
      FooNonPointerBase&lt;T&gt; &gt;::type {
  };
  
  int main(int argc, char * argv[])
  {
      int someInt = 1020;
  #if DEMONSTRATE_ERROR_CASES
      Foo&lt;int*&gt;().valid_if_not_pointer(&amp;someInt);
      Foo&lt;int&gt;().valid_if_pointer(304);
  #else
      Foo&lt;int*&gt;().valid_if_pointer(&amp;someInt);
      Foo&lt;int&gt;().valid_if_not_pointer(304);
  #endif
      return 0;
  }
  </code></pre>
  
  <p>But if this is not broken <em>(is it?)</em>, it's certainly not following a good general methodology for how to turn on and off methods in a templated class based on sniffing the type for traits.  Is there a better solution?</p>