title: Template constructor selected over non-template overload
body: <p>I have code similar to the following snippet:</p>
  <pre><code>#include &lt;iostream&gt;
  #include &lt;string&gt;
  
  struct Base
  {
      Base(int in) : _val(in) {}
      Base(Base &amp;&amp;b) = default;
      Base(Base const &amp;b) = default;
  
      int _val;
  };
  
  struct Wrapper : public Base
  {
      template &lt;typename Type&gt;
      Wrapper(Type &amp;&amp;val) : Base(std::move(val)) { _val++; std::cerr &lt;&lt; &quot;rval incr\n&quot;; }
      template &lt;typename Type&gt;
      Wrapper(Type const &amp;val) : Base(val) { _val++; std::cerr &lt;&lt; &quot;lval incr\n&quot;; }
      Wrapper(Wrapper &amp;&amp;wrap) : Base(wrap._val) {std::cerr &lt;&lt; &quot;rval wrap\n&quot;; }
      Wrapper(Wrapper const &amp;wrap) : Base(wrap._val) {std::cerr &lt;&lt; &quot;lval wrap \n&quot;; }
  };
  
  int main(int, char**)
  {
      int val = 10;
      Base b(val);
      std::cerr &lt;&lt; (Wrapper(b)._val == 11 ? &quot;fair&quot; : &quot;nope&quot;) &lt;&lt; '\n';
      Wrapper w(20);
      std::cerr &lt;&lt; (Wrapper(std::move(w))._val == 21 ? &quot;fair&quot; : &quot;nope&quot;) &lt;&lt; '\n';
      Wrapper w2(30);
      std::cerr &lt;&lt; (Wrapper(w2)._val == 31 ? &quot;fair&quot; : &quot;nope&quot;) &lt;&lt; '\n';
      return 0;
  }
  </code></pre>
  <p>I ran it through godbolt (<a href="https://gcc.godbolt.org/z/rzs8xoWeE" rel="nofollow noreferrer">https://gcc.godbolt.org/z/rzs8xoWeE</a>) and it confirmed what I was seeing in my development environment. I assumed initially this was a perhaps a compiler bug but it seems like all compilers agree on the following output:</p>
  <pre><code>rval incr
  fair
  rval incr
  rval wrap
  fair
  rval incr
  rval incr
  nope
  </code></pre>
  <p>Why does it not call the <code>Wrapper</code> constructor overloads (resulting in 'rval wrap' in the second to last line of output)? In the context of functions as far as I understand it non-template overloads should be preferred over templated functions. Is that not true for this context or is there a different resolution taking precedence here?</p>
  <p>Thanks.</p>
  <p>Edit:
  There was misunderstanding as to which constructor variants were viable:</p>
  <blockquote>
  <p>When you wrote: Wrapper(w2) note the argument w2 is an lvalue and so move ctor is not viable. You can confirm that this is indeed the case by changing it with Wrapper(std::move(w2)) and you'll get your expected output. Note i already did this in my second comment above and i also mentioned there that you'll get the expected output. The reason is also explained in the dupe. Please read the dupe.</p>
  </blockquote>
  <p>Adding an overload with the signature <code>Wrapper(Wrapper &amp;wrap)</code> solved my problem.</p>