The answer to the first part is that initializing an object from a value and linking a link to a value are considered equally good (both are “exact matches” when resolving overloads), so the parameter reference is not displayed. Rather, you must specify it exactly. For a corresponding example, consider a hypothetical construction
T x = f();
where T is (throughout this thought experiment) what you must infer. What should be x be - an object or a link? What will it depend on? The expression on the right matters, of course, and the type of this value is always the type of the object. How do you decide? You can request a category of expression values, but this is too subtle. So instead, you should say what you want:
T x = f();
In C ++, this mechanism is really available if you replace T with auto . The same rules apply to subtracting template arguments for function templates.
Now about how to solve your problem. The usual idiom is to make the function template always take a reference, and then redirect the argument to an internal call:
template <typename T> void func(T && t) { f(std::forward<T>(t)); };
Now the func parameter is always a reference in any specialization (but thanks to a strange rule called "collapsing reference", it can be either an lvalue or an rvalue), and this value is sent from the same group of value categories to f , and this overload resolution on f allows you to choose lvalue-reference overloads when the original argument to func was an lvalue.
Kerrek SB
source share