It wasn't in 2011, because:
- We didn't have
auto
return type deduction for functions (that's a C++14 feature), and
- We didn't have
auto&&
parameters for functions (that's a C++20 feature), and
- Rvalue references were not implicitly moved from in return statements (that's also a C++20 feature)
But in C++20, yes, that is now a valid way to implement decay_copy
. auto
deduction does decay, return v;
implicitly forwards, and everything else is the same.
I guess technically there's an edge case like:
struct X {
X();
X(X&);
};
With the original formulation of decay_copy(X{})
, this is ill-formed (there's no viable constructor for constructing an X
from an rvalue X
). With the new formulation under the existing C++20 rules, it becomes well formed and invokes the non-const copy constructor (because we do this two-step overload resolution).
If P2266 is adopted though, then they would be exactly equivalent because return v;
would always treat v
as an rvalue, exactly as the existing formulation does.