title: Why does importing constructors with 'using' cause a different overload to be selected?
body: <p>It would appear that overload resolution functions slightly differently for imported constructors and explicitly declared constructors but I do not understand why.</p>
  <p>Consider the following code:</p>
  <pre><code>struct BaseBase { int val; };
  
  struct Base : BaseBase
  {
      int test;
  
      Base() : BaseBase{}, test(0) {}
      Base(const Base&amp; other) : BaseBase(other), test(1) {}
      Base(const BaseBase&amp; other) : BaseBase(other), test(2) {}
  };
  
  struct Derived : Base
  {
  #if 1
      Derived(const Base&amp; other) : Base(other) {}
      Derived(const BaseBase&amp; other) : Base(other) {}
  #else
      using Base::Base;
  #endif
  };
  
  int foo()
  {
      BaseBase bb{};
      Base b1{bb};
      Derived d1{b1};
      return d1.test;
  }
  </code></pre>
  <p>Here <code>foo()</code> returns 1, proving that the <code>Base&amp;</code> copy constructor was called. This is what I would expect because the constructor was passed a <code>Base</code> instance.</p>
  <p>If I change the <code>#if 1</code> to <code>#if 0</code>, then instead of defining its own constructors, <code>Derived</code> gets the constructors defined in <code>Base</code>. I would therefore expect it to have the following constructors:</p>
  <pre><code>Derived()
  Derived(const Base&amp; other)
  Derived(const BaseBase&amp; other)
  </code></pre>
  <p>which are the same ones defined in-place in <code>Derived</code>, plus a default constructor. However now <code>foo()</code> returns 2 instead, proving that the <code>BaseBase&amp;</code> constructor was called even though the code at the call-site has not changed and is still using a <code>Base</code> instance.</p>
  <p>The code is also available <a href="https://godbolt.org/#z:OYLghAFBqd5QCxAYwPYBMCmBRdBLAF1QCcAaPECAM1QDsCBlZAQwBtMQBGAFlICsupVs1qhkAUgBMAISnTSAZ0ztkBPHUqZa6AMKpWAVwC2tEAFZSW9ABk8tTADljAI0zEQAdlIAHVAsLqtHqGJuY%2BfgF0tvZORq7uXkoqanQMBMzEBMHGphZJmKqBaRkE0Y4ubp6K6ZnZoXk1pXblcZUeAJSKqAbEyBwA5AoExAaqANTSzEqTSmPiHtJjdgRjAG5s4gDMi/MAIluyAAwAguInQyPjM5hjIBNTmNdnpwvPY%2B9L9GMEmEMHz28PtcIO1bvdpg95rIPLtSN9fgQIIdQVC9oD3sC0LQhuDMFIAGxjVAEBBuUF3a7A4mk4ideFDCCcFGvGHo3EQLE4ymQySE6lksHcpQQfm0uE/BmSZnQ/YnNHbAHnYajFa7Nx4VaYdCCyFy15yySbPBUMacNlq4garUcuhcnl8kkCikPEWO2lzFmy44fMYWq3oG3YlZCvG8olu8ns0XStEGzbKJRsgz%2BUS4kAgJ4Kk4%2BgD0ObGxwUYyoGTGUzGAEkwP0jGWAO4ZTDihB4It4Iy%2BTJFx3F/SsVB1uzAMac5WqEgKEBsvO%2B9WagPtaf5v3zwN2xNh6NL2eW1ej3FPTcRgGGqzGgGsrOnE7LXuoEEXo7eoEPa5jZzOVGXp8%2Bt/OM0LB%2B8o/h8K5amM6AAdI/7AWyxCYAQPS0BBnAAHQSgQ/x6rs/SdKwID9GY/SkKY/SHMRqAETochyGMCjdL0NxSJsnDEQQBHke0nQANbmIcQgEdwxGkeRpCUf0xGTvx7FkbhpBwLAMCICgqAdng7BkBQNpqRpKDCKInCHEZpBUOpPzEJOEDOBxxHOHYGQAJ4EaxpBoEYRhaAQADytCsE5smkFgRgiMA7A2YFeDwYUmqTgFmAAB4FAYPzOcRyzKOFrB4M4xCOXoWCpaQwztqlnQ0PQTBsBwPD8II%2BliDRMhCNlk6QJ0qDeCk2IEQAtF5khjD1QzoFsuwSDIcicB4knKAUXWaNodSmJwljaGUsTxIIvj%2BF1S1bREXXrRU7grfkhSpI0e2nbN520MUmRHa0J3VCUV0vQ9zQbZUTJdD0fRcHhBFESR4XifFAAc%2BI9fi3AjvVpqHKhiOHGMEC4IQJBzIaK1jHoOluFjLGgtRE0yGxNlcaQvGbJsqE0/TDOM/iAn9EJpBGHxIMBeJkkgNJFPyUpEBIG53jqW45CUKL4vuKsyDeN4AD6qycAAnIrkgeIr8UwyZZluJZ1kBXZtCOYVbkefQPl%2BeFQUhWFAX4FFagxeFCVJSl/Quel%2BEBVlOV5RgAwucVHNe3J5WMCwYU1QImxCCFKCNfI/utSCYmdYEsV9QNQ0EOgSek9IU0zckgQLbo%2Bg5IIViPZtK3bZEQRV6EDcHYEdffYoN1dfdWQt8t3dlxdJSd89QyvQPggTx9MTHQDv2MQvvvAyJFEETrsNGAoctrGrqGa6j6NEMQhM43jYsaYTmzE8n5OyZTpLMFg7jp77bMc2Y/Fr2JBG8/zD8eKc19psYSoM/5FQpoDfokgwHcwgTJTinRNQWXLtwIAA%3D%3D" rel="nofollow noreferrer">here on Compiler Explorer</a>.</p>
  <p>My understanding of the overload resolution rules is that all else being equal, the &quot;most specific&quot; (IE furthest down the inheritence hierarchy) overload is selected. This is what happens when <code>Derived</code> has its own constructors but not when it imports constructors from <code>Base</code>. Why is the behaviour different? Why isn't the <code>Base</code> constructor used?</p>