https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86430

            Bug ID: 86430
           Summary: ambiguous overload?
           Product: gcc
           Version: 8.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: zhonghao at pku dot org.cn
  Target Milestone: ---

The code is as follow:

// snip
template<typename T>
struct Const { typedef void const type; };

template<typename T>
void f(T, typename Const<T>::type*) { } // T1

template<typename T>
void f(T, void const *) {  } // T2

int main() { void *p = 0; f(0, p); }
// snap

g++ produces the following errors:

error: call of overloaded 'f(int, void*&)' is ambiguous
 int main() { void *p = 0; f(0, p); }

I tried clang++. It accepts the above code. My understanding is as follows:

template<typename T>
void f(T, typename Const<T>::type*) // T1

template<typename T>
void f(T, void const *) // T2

We're going to deduce  

(unique-1, Const<unique-1>::type*) -> 
(T,        void const*) // T1 -> T2

and

(unique-1, void const*) -> 
(T,        Const<T>::type*) // T2 -> T1

The first one takes T = unique-1 but fails at matching "void const*" to
"Const<unique-1>::type*". So this round fails for the second parameter. 

The second one takes T = unique-1. The second is a non-deduced context, thus
not compared, and this does not mismatch. So this round succeeds for parameter
2.

So we have: For parameter 1, each template is at least as specialized as the
other one. For parameter 2, T1 -> T2 did not succeed, so T1 is not at least as
specialized as T2 - but not vice versa (T2 -> T1 suceeded). Thus for parameter
2, T2 is more specialized.

It follows that T2 overall is more specialized that T1.

As a result, the overload is not ambiguous. Please correct me, if I am wrong.

Reply via email to