Template argument deduction is done by comparing the return type of
the
conversion function template
(call it
P)
with the type that is
required as the result of the conversion (call it
A; see [dcl.init], [over.match.conv], and [over.match.ref]
for the determination of that type)
as described in [temp.deduct.type].

If P is a reference type, the type referred to by P is used in place
of P for type deduction and for any further references to or transformations of
P in the remainder of this subclause.

If
A
is not a reference type:

- If P is an array type, the pointer type produced by the array-to-pointer standard conversion is used in place of P for type deduction; otherwise,
- If P is a function type, the pointer type produced by the function-to-pointer standard conversion is used in place of P for type deduction; otherwise,
- If P is a cv-qualified type, the top-level cv-qualifiers of P's type are ignored for type deduction.

If
A
is a cv-qualified type, the top-level cv-qualifiers of
A's
type are ignored for type deduction.

In general, the deduction process attempts to find template argument
values that will make the deduced
A
identical to
A.

However, there are four cases that allow a difference:

- If the original A is a reference type, A can be more cv-qualified than the deduced A (i.e., the type referred to by the reference)
- If the original A is a function pointer type, A can be “pointer to function” even if the deduced A is “pointer to noexcept function”.
- If the original A is a pointer-to-member-function type, A can be “pointer to member of type function” even if the deduced A is “pointer to member of type noexcept function”.
- The deduced A can be another pointer or pointer-to-member type that can be converted to A via a qualification conversion.