http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3255.html defines decay_copy
as follows:
template<typename T>
std::decay_t<T> decay_copy(T&& v)
{
return std::forward<T>(v);
}
I just wonder:
Is it equivalent to the following simpler one?
auto decay_copy(auto&& v)
{
return v;
}
CodePudding user response:
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.