Generally speaking, for successful deduction, an argument must have the same general appearance as a parameter. There are some exceptions from which T && can be deduced from U & (by choosing T = U & ), but this exception was not indicated.
14.8.2.5 Derivation of template arguments from the type [temp.deduct.type]
8 Template argument T , template TT template argument or non-type i template argument can be output if P and A have one of the following forms:
[...]
T&
T&&
[...]
This is not entirely clear, but this requires P (parameter) and A (argument) for both forms. They must be T&& or both T&& . Exceptions, circumstances in which T && can be deduced from U & , are performed by changing T && to plain T before the comparison is performed, in limited circumstances:
10 Similarly, if P has a form containing (T) , then each type of parameter P i corresponding list of parameter types P compared with the corresponding type of parameter A i corresponding list of parameters of type A If P and A are types of functions that have arisen from subtraction when accepting the address of the function template (14.8.2.2) or when deriving template arguments from the function declaration (14.8.2.6) and P i and A i are parameters of the top list of type parameters P and A , respectively, P i configured if it is an rvalue reference to the cv-unqualified template parameter, and A i is an lvalue, in this case the type of P i changes as the type of the template parameter (i.e., T&& changes simply to T ). [...]
and
14.8.2.1 Deriving template arguments from a function call [temp.deduct.call]
3 [...] If P is the rvalue reference to the cv-unqualified template parameter and the argument is lvalue, instead of A , the type is "lvalue reference to A " for the type. [...]
but a similar exception does not apply to your scenario.
This is the very principle that makes
template <typename T> struct S { }; template <typename T> void f(S<const T>) { } int main() { f(S<void()>()); }
invalid: const T cannot be inferred from void() , although T = void() will give exactly this result, and the call f<void()> will succeed.
Wintermute's deleted answer showed that you can use
template <typename... Types>
instead: it allows Types to be displayed as lvalue links, as rvalue links, or as non-links, depending on the type of value .