title: C++17: user-defined constructor is always called and operator+ overloading not working for child class
body: <p>Overall, I'm implementing a class to modularize an unsigned number (a wrapper for unsigned types). I want my class to meet this conditions:</p>
  
  <ul>
  <li>Do all the operations a modular number can do.</li>
  <li>The underlined value_type must be of unsigned type, but the template parameter can be convertible to an unsigned type (for example, if the template parameter type is int, then the underlined value_type will be unsigned).</li>
  <li>I want a derived class that can perfoms extra operations (like dividing, for example).</li>
  <li>It must admit the operations to be compatible with types convertible to value_type (for example, <code>Test&lt;N&gt; + unsigned</code>, <code>Test&lt;N&gt; + UnsignedWrapper</code>, ...).</li>
  <li>Must allow implicit conversion to the underlined value_type.</li>
  <li>Must allow explicit conversions from <code>Test&lt;N&gt;</code> to <code>Test&lt;K&gt;</code> (same for TestChild), being N and K different numbers.</li>
  </ul>
  
  <p>I reduced my problem to this code:</p>
  
  <p><strong>test.hpp:</strong></p>
  
  <pre><code>#include &lt;type_traits&gt;
  #include &lt;iostream&gt;
  
  // As you can see, C++17 is needed
  template &lt;auto UInt&gt;
  class Test{
  
     public:
        //I need the type to be unsigned
        typedef std::make_unsigned_t&lt;decltype(UInt)&gt; value_type;
        static constexpr value_type N = static_cast&lt;value_type&gt;(UInt);
  
        Test (const value_type&amp; k = 0) : n(k%N){
           // Just to show that this constructor is always called
           std::cout &lt;&lt; "Test user-defined constructor " &lt;&lt; k &lt;&lt; std::endl;
        }
  
        Test&amp; operator+= (const Test&amp; k){
           n = (n+k.n)%N;
           return *this;
        }
  
        template&lt;typename U&gt;
        Test&amp; operator+= (const U&amp; other){
           n = (n+static_cast&lt;value_type&gt;(other))%N;
           return *this;
        }
  
        template&lt;auto UInt2&gt;
        explicit operator Test&lt;UInt2&gt;() const{
           return Test&lt;UInt2&gt;(n);
        }
  
        operator value_type() const{
           // Just to show that this is called only once
           std::cout &lt;&lt; "Casting to value_type" &lt;&lt; std::endl;
           return n;
        }
  
     protected:
  
        value_type n;
  };
  
  template&lt;auto UInt&gt;
  class TestChild : public Test&lt;UInt&gt;{
  
     public:
  
        typedef typename Test&lt;UInt&gt;::value_type value_type;
        static constexpr value_type N = Test&lt;UInt&gt;::N;
  
        TestChild (const value_type&amp; k = 0) : Test&lt;UInt&gt;(k){}
  
        template&lt;auto UInt2&gt;
        explicit operator TestChild&lt;UInt2&gt;() const{
           return TestChild&lt;UInt2&gt;(this-&gt;n);
        }
  };
  
  // I prefer to define binary operators outside the class and leave the logic inside the class
  template&lt;auto UInt&gt;
  const Test&lt;UInt&gt; operator+ (const Test&lt;UInt&gt;&amp; lhs, const Test&lt;UInt&gt;&amp; rhs){
     return Test&lt;UInt&gt;(lhs) += rhs;
  }
  
  template&lt;auto UInt&gt;
  const TestChild&lt;UInt&gt; operator+ (const TestChild&lt;UInt&gt;&amp; lhs, const TestChild&lt;UInt&gt;&amp; rhs){
     return TestChild&lt;UInt&gt;(lhs) += rhs;
  }
  
  template&lt;auto UInt, typename U&gt;
  const Test&lt;UInt&gt; operator+ (const Test&lt;UInt&gt;&amp; lhs, const U&amp; rhs){
     return Test&lt;UInt&gt;(lhs) += static_cast&lt;typename Test&lt;UInt&gt;::value_type&gt;(rhs);
  }
  
  template&lt;auto UInt, typename U&gt;
  const Test&lt;UInt&gt; operator+ (const U&amp; lhs, const Test&lt;UInt&gt;&amp; rhs){
     return Test&lt;UInt&gt;(rhs) += static_cast&lt;typename Test&lt;UInt&gt;::value_type&gt;(lhs);
  }
  
  /****************************************************************************/
  
  
  int main(){
     // It doesn't matter how I initialize the varible,
     // always calls the user-defined constructor
     TestChild&lt;89209&gt; x(347), y(100), z(1000);
     TestChild&lt;89133&gt; t = static_cast&lt;decltype(t)&gt;(x);
  
     Test&lt;10000&gt; u = static_cast&lt;decltype(u)&gt;(y), v(z);
     Test&lt;19847&gt; w(u);
     TestChild&lt;1297&gt; r(u);   //Here it seems that it casts u to its member value_type
  
     u = u + v;
     //u = u + w;   //The compiler complains about ambiguity (don't know how to fix it without casting w)
     //x = y + z;   //No idea what's happening here
  }
  </code></pre>
  
  <p>If I uncomment the last two sums, I get this error when compiling with <code>g++ -std=c++17 -O2 -Wall -Wextra -pedantic test.cpp -o test</code>, with GCC 7.2.0 in Ubuntu 16.04 LTS:</p>
  
  <pre><code>test.cpp: In function ‘int main()’:
  test.cpp:92:10: error: ambiguous overload for ‘operator+’ (operand types are ‘Test&lt;10000&gt;’ and ‘Test&lt;19847&gt;’)
      u = u + w;   //The compiler complains about ambiguity (don't know how to fix it without casting w)
          ~~^~~
  test.cpp:92:10: note: candidate: operator+(Test&lt;10000&gt;::value_type {aka unsigned int}, Test&lt;19847&gt;::value_type {aka unsigned int}) &lt;built-in&gt;
  test.cpp:69:18: note: candidate: const Test&lt;UInt&gt; operator+(const Test&lt;UInt&gt;&amp;, const U&amp;) [with auto UInt = 10000; U = Test&lt;19847&gt;]
   const Test&lt;UInt&gt; operator+ (const Test&lt;UInt&gt;&amp; lhs, const U&amp; rhs){
                    ^~~~~~~~
  test.cpp:74:18: note: candidate: const Test&lt;UInt&gt; operator+(const U&amp;, const Test&lt;UInt&gt;&amp;) [with auto UInt = 19847; U = Test&lt;10000&gt;]
   const Test&lt;UInt&gt; operator+ (const U&amp; lhs, const Test&lt;UInt&gt;&amp; rhs){
                    ^~~~~~~~
  test.cpp: In instantiation of ‘const TestChild&lt;UInt&gt; operator+(const TestChild&lt;UInt&gt;&amp;, const TestChild&lt;UInt&gt;&amp;) [with auto UInt = 89209]’:
  test.cpp:93:12:   required from here
  test.cpp:65:35: error: could not convert ‘(* &amp; lhs).TestChild&lt;89209&gt;::&lt;anonymous&gt;.Test&lt;89209&gt;::operator+=&lt;TestChild&lt;89209&gt; &gt;((* &amp; rhs))’ from ‘Test&lt;89209&gt;’ to ‘const TestChild&lt;89209&gt;’
      return TestChild&lt;UInt&gt;(lhs) += rhs;
                                     ^~~
  </code></pre>
  
  <p>As you can see, it doesn't matter how I initialize the variables; the user-define constructor is always called. I initially thought that a casting to the underlined value_type was called, but then I realized that's not the case, because I explicited the casting to value_type and it still doesn't do any casting. I think the compiler must be doing something weird to avoid the copy constuctor or copy assignment, but I don't really know.</p>
  
  <p>I understand the ambiguity in <code>u = u + w;</code>, which can be fixed by casting w; but I'd like to find a way to do it without casting (I mean, maybe deducing that u is of one type, so the sum must return that type).</p>
  
  <p>The second sum is the one I don't really understand what the compiler error means. I've been looking for a solution for a week or so, and I can't figure out what to do. It seems that it gets the function signature right (the correct overload of operator+ is called), but then complains about some weird type conversion.</p>
  
  <p>Maybe I'm laking in the design of the class. If that's the case, let me know.</p>
  
  <p><strong>EDIT:</strong> Note that <code>u = w + u</code> should also work, but it leads to another ambiguity, so I'm deciding to force the casting in order to do the operation.</p>