Excuse the bad title...
So, normally in a function like this:
template <class T>
void f(T&& i){
}
T&&
is a universal reference. In a context like this it is an rvalue-reference:
template <class T>
struct s{
void f(T&& t){}
};
This makes sense, as T
is a fixed type relative to s
of which f()
is a method.
However, apparently in this context:
template <class T, unsigned n>
std::array<T, n>
f(T&&){
}
T&&
is an rvalue-reference as well. This case is different from the above one though. So, what is the reason for T&&
being an rvalue-reference here as well rather than a universal one?
That's because you supplied the parameter type explicitly (I am assuming this much, but this is the only way to make your example compile).
f<int,5>
performs no type deductions at all, and its parameter is int&&
. There is no reference collapsing going on.
You could work around this by writing the f
template as such:
template<unsigned n, typename T>
array<decay_t<T>, n>
f(T&& t);
Now, t
is a forwarding/universal reference if you don't provide the second template argument explicitly.