Let's consider the following code:
template<typename T>
void f(T&);
int x=0;
int y=1;
f(x+y);
It seems that type deduction happens for this code. But why? There is no reference collapsing rule that will produce int&& at the end.
According to the C++17 standard, [temp.deduct.call]/3:
... If
P
is a reference type, the type referred to byP
is used for type deduction. ...
Here, P
is T&
, so the compiler removes the reference and compares T
with the type of the argument x+y
. It therefore deduces T
as int
. Then, at the overload resolution stage, an error occurs because an rvalue of type int
cannot be bound to the parameter of type int&
.
Template argument deduction must occur before overload resolution, because otherwise the compiler would not know what parameter types to use for overload resolution.