The following example is likely wrongly discussed in standard text of [over.match.class.deduct]

Such examples are also managed by the major compilers (gcc, mvsc, clang) differently from the standard comments.

p6, Example 2:


template <class T> struct A { explicit A(const T&, ...) noexcept; // #1 A(T&&, ...); // #2 }; int i; ... template <class T> A(const T&, const T&) -> A<T&>; // #3 template <class T> explicit A(T&&, T&&) -> A<T>; // #4 ... A a7 = {0, i}; // error: #3 deduces to A<int&>, #1 and #2 declare same constructor A a8{0,i}; // error: #3 deduces to A<int&>, #1 and #2 declare same constructor

The example reads that the selected guide is from the (user-defined) deduction guide #3.

However, ok for #4 not matching, as there T is ambiguously deduced as int from first function parameter and int& from second one.
Ok that #3 is better than #1 as the notional constructor related to #1 has ellipsis, with lowest priority in overload resolution.
But, #2 is not worse than #3. Indeed, for #2 T is deduced as int and A(int&&, ...) is the winner for the first argument.
Since #3 is the winner for second argument, here we have ambiguity.
Ambiguity is confirmed also by clang (that correctly lists #2 and #3 as candidates), by mvsc (it lists also #4, a bit weird, but never mind), and by gcc that just reads about argument deduction failed.

In conclusion, I guess that "#3 deduces to A<int&> is misleading.
Additionally, the statement "#1 and #2 declare same constructor" is also misleading: they both matching the list-initialization with {0,i} and deducing int, but they do not lead to the same constructor (const in& is not int &&).



I hope you may also consider the following doubt that I was studying when I found the problem above: