title: Overload ambiguity in direct initialization with conversion functions
body: <p>The following code is used as an example to help me understand the implicit conversion sequence and function overload in the process of direct initialisation. The example is rather simple.</p>
  <p>Class <code>B</code> doesn't have any constructor that accepts object of type <code>C</code>. Class <code>C</code>, on the other hand, implements two user-define conversion operators, see line [5] and [6]. (Qualifier <code>const</code> on line [3] is to help me understand the impact of qualifier on function overloading, in case you question the intent of that line.)</p>
  <pre><code>class B;
  
  class A {
  public:
      A() {}
      operator B();
  };
  
  class B {
  public:
      B() {std::cout &lt;&lt; &quot;default constructor B::B() \n&quot;;}                            // [1]
      explicit B(A&amp;) { std::cout &lt;&lt; &quot;B::B(A&amp;) \n&quot;; }             // [2]
      explicit B(const A&amp;) { std::cout &lt;&lt; &quot;B::B(const A&amp;) \n&quot;; } // [3]
  };
  
  A::operator B() { std::cout &lt;&lt; &quot;conversion A::B() \n&quot;; return B(); } // [4]
  
  // Ambiguity issue
  class C {
  public:
      C() {}
      explicit operator A() { std::cout &lt;&lt; &quot;conversion C::A() \n&quot;; return A(); } // [5]
      explicit operator B() { std::cout &lt;&lt; &quot;conversion C::B() \n&quot;; return B(); } // [6]
  
  //  explicit operator A() { std::cout &lt;&lt; &quot;conversion C::A() \n&quot;; return A(); } // [7]
  //  operator B() { std::cout &lt;&lt; &quot;conversion C::B() \n&quot;; return B(); }          // [8]
  
  // Combinations that trigger ambiguous overload.    
  //  operator A() { std::cout &lt;&lt; &quot;conversion C::A() \n&quot;; return A(); }          // [9]
  //  explicit operator B() { std::cout &lt;&lt; &quot;conversion C::B() \n&quot;; return B(); } // [10]
  
  //  operator A() { std::cout &lt;&lt; &quot;conversion C::A() \n&quot;; return A(); }          // [11]
  //  operator B() { std::cout &lt;&lt; &quot;conversion C::B() \n&quot;; return B(); }          // [12]
  };
  
  int main() {
      C c;     // [21]
      B b (c); // [22]
  }
  </code></pre>
  <p>At [22], when both conversion operators of <code>C</code> are labelled <code>explicit</code> ([5] and [6]), or only <code>C::A()</code> is <code>explicit</code> ([7] and [8]), compiler is silent and printing</p>
  <pre><code>conversion operator C::B() 
  default constructor B::B() 
  </code></pre>
  <p>which suggests that (correct me if I am wrong), per direct initialisation, object <code>c</code> is converted into a temporary object of type <code>B</code> via its conversion function. This can be understood, since conversion into type <code>B</code> appears to be more straightforward (than first into <code>A</code> and to <code>B</code>) as the target type is exactly <code>B</code>.</p>
  <p>Combinations [9,10] and [11,12], i.e. making conversion to type <code>C::A()</code> implicit, trigger the following error on ambiguous overload:</p>
  <pre><code>test.cpp:189:12: error: call of overloaded ‘B(C&amp;)’ is ambiguous
    189 |     B b (c);
        |            ^
  test.cpp:94:14: note: candidate: ‘B::B(const A&amp;)’
     94 |     explicit B(const A&amp;) {              
        |              ^
  test.cpp:85:7: note: candidate: ‘constexpr B::B(const B&amp;)’
     85 | class B {
        |       ^
  test.cpp:85:7: note: candidate: ‘constexpr B::B(B&amp;&amp;)’
  </code></pre>
  <p>I don't understand this ambiguity in overload. Indeed, converting <code>c</code> to type <code>A</code> and then invoking a constructor of <code>B</code> is one option. But, direct conversion into <code>B</code> is available and that conversion sequence appears to be &quot;shorter&quot; and is thus &quot;better&quot;.</p>
  <p>I am sure that I missed some implicit conversion or overload resolution rules from the C++ reference website. Can anyone point out to me the relevant &quot;rules&quot;? Compiler version is <code>g++ 9.3.0</code>.</p>