title: enable_if with copy/move assignment operator
body: <p>I have a class in which I want to enable the copy/move assignment operators only if a type parameter to the class is nothrow copy/move constructible respectively. So I tries this:</p>
  
  <pre><code>#include &lt;type_traits&gt;
  
  template&lt;typename T&gt;
  struct Foobar {
  
      Foobar(T value) : x(value) {}
      Foobar(const Foobar &amp;other) : x(other.x) {}
      Foobar(Foobar &amp;&amp;other) : x(std::move(other.x)) {}
  
      template&lt;bool Condition = std::is_nothrow_copy_constructible&lt;T&gt;::value,
               typename = typename std::enable_if&lt;Condition&gt;::type&gt;
      Foobar &amp;operator=(const Foobar &amp;rhs) {
          x = rhs.x;
          return *this;
      }
  
      template&lt;bool Condition = std::is_nothrow_move_constructible&lt;T&gt;::value,
               typename = typename std::enable_if&lt;Condition&gt;::type&gt;
      Foobar &amp;operator=(Foobar &amp;&amp;rhs) {
          x = std::move(rhs.x);
          return *this;
      }
  
      T x;
  };
  
  int main() {
      Foobar&lt;int&gt; foo(10);
      Foobar&lt;int&gt; bar(20);
  
      foo = bar;
      foo.operator=(bar);
  
      return 0;
  }
  </code></pre>
  
  <p>Now, Clang gives me the following error:</p>
  
  <pre><code>enable_if_test.cpp:31:9: error: object of type 'Foobar&lt;int&gt;' cannot be assigned because its copy assignment operator is implicitly
        deleted
      foo = bar;
          ^
  enable_if_test.cpp:8:5: note: copy assignment operator is implicitly deleted because 'Foobar&lt;int&gt;' has a user-declared move
        constructor
      Foobar(Foobar &amp;&amp;other) : x(std::move(other.x)) {}
      ^
  enable_if_test.cpp:32:9: error: call to deleted member function 'operator='
      foo.operator=(bar);
      ~~~~^~~~~~~~~
  enable_if_test.cpp:4:8: note: candidate function (the implicit copy assignment operator) has been implicitly deleted
  struct Foobar {
         ^
  enable_if_test.cpp:12:13: note: candidate function [with Condition = true, $1 = void]
      Foobar &amp;operator=(const Foobar &amp;rhs) {
              ^
  enable_if_test.cpp:19:13: note: candidate function [with Condition = true, $1 = void] not viable: no known conversion from
        'Foobar&lt;int&gt;' to 'Foobar&lt;int&gt; &amp;&amp;' for 1st argument
      Foobar &amp;operator=(Foobar &amp;&amp;rhs) {
              ^
  2 errors generated.
  </code></pre>
  
  <p>Now, I included the explicit call to the assignment operator to showcase the weirdness of the error. It just says that my template is a candidate function and gives no reason for why it is not chosen.</p>
  
  <p>My guess here is that since I defined a move constructor, the compiler implicitly deleted the copy assignment operator. Since it is implicitly deleted, it doesn't even want to instantiate any template. Why it behaves like this I do not know, however.</p>
  
  <p>How can I achieve this behavior?</p>
  
  <p>(Note: The actual code has legitimate reasons to define each of the members, I'm aware that it is useless here.)</p>