title: C++ member function is ambiguous
body: <p>I've seen there are already questions about ambiguous error in C++, but this is some kind of different.</p>
  
  <p>Let's say we have code like following:</p>
  
  <pre><code>#include &lt;iostream&gt;
  
  #define LDBG(msg) \
    std::cout &lt;&lt; "[" &lt;&lt; __FUNCTION__ &lt;&lt; " " &lt;&lt; __LINE__ &lt;&lt; "] " &lt;&lt; msg &lt;&lt; std::endl;
  
  template&lt;typename T&gt;
  struct AClass{
    AClass(T a) {}
  
    void Foo(const AClass&lt;T&gt; &amp;other){
      LDBG("")
    }
  
    void Foo(const T &amp;key) const{
      LDBG("")
    }
  };
  
  int main(){
    AClass&lt;int&gt; a1{1};
    AClass&lt;int&gt; a2{2};
  
    a1.Foo(1);
    a1.Foo(a2);
  
    LDBG("")
    return 0;
  }
  </code></pre>
  
  <p>This will produce compiling error like:</p>
  
  <pre><code>error: call to member function 'Foo' is ambiguous
      a1.Foo(1);
      ~~~^~~
  note: candidate function
      void Foo(const AClass&lt;T&gt; &amp;other){
           ^
  note: candidate function
      void Foo(const T &amp;key) const{
           ^
  1 error generated.
  </code></pre>
  
  <p>The error will just be gone if:</p>
  
  <ol>
  <li>Remove the const at line 14 ( <code>void Foo(const T &amp;key) const{</code> )</li>
  </ol>
  
  <p>or 2. Add a const at the end of <code>void Foo(const AClass&lt;T&gt; &amp;other)</code> too</p>
  
  <p>or 3. Change the Constructor into <code>AClass() {}</code> (also the relative Initialization of a1 and a2 in main function)</p>
  
  <p>or some other ways.</p>
  
  <p>How do these 3 or more rectification wrok, what's the problem of the original?</p>