When you say func<double>(n) , there are no arguments, because you specify an argument, and so the choice is between func(double &&) and func(const double &) . The first is not viable since the rvalue reference cannot communicate with the lvalue (namely n ).
Only func(n) performs the output of the argument. This is a complex topic, but in a nutshell you have two possible candidates:
T = double &: func(T &&) --> func(double &) (first overload) T = double: func(const T &) --> func(const double &) (second overload)
The first overload is strictly better, because it requires less conversion of the argument value (namely, from double to const double ).
A magic ingredient is a link that compresses " , which means that T && can be an lvalue reference when T itself a reference type (especially double & && becomes double & , and this allows the first conclusion).
Kerrek SB
source share