from Shower Thoughts to Ruminations

Alternative `std::decay` Implementation

What’s std::decay?

decay is a metafunction added to the <type_traits> header in C++11. A metafunction is a function (in the mathematical sense) that takes types as arguments rather than values. A simpler metafunction to describe is add_const which takes any arbitrary type and adds const to it. For example:

The function impl takes an argument by value, so any argument of type T that
gets passed to it will go through the type transformations necessary for
pass-by-value sematics. Notice that this is exactly what we want for decay!

I pass an rvalue reference of T to impl, and the deduced type U is the
result we want for decay.

So What?

Not only is the implementation simpler this way, but it also follows the
DRY (Don’t Repeat Yourself) principle. Suppose the definition of pass-by-value
transformations were to change in the standard. In the current state, at least 4
modifications are required.

Rules for template type deduction

Definition of decay

Implementation of template type deduction in the compiler

Implementation of decay in the standard library

If we were to piggy-back on the rules of template type deduction to define
decay instead, (1) and (3) still needs to be done but we get (2) and (4)
for free.

I also think it allows for stronger claims about what decay does. Here’s a
note about decay from N3797:

[ Note: This behavior is similar to the lvalue-to-rvalue (4.1),
array-to-pointer (4.2), and function-to-pointer (4.3) conversions applied when
an lvalue expression is used as an rvalue, but also strips cv-qualiﬁers from
class types in order to more closely model by-value argument passing.
— end note ]

What does “more closely model by-value argument passing” mean here? It
sounds to me like it doesn’t exactly model by-value argument passing. I
think leveraging the existing rules of template type deduction would allow us to
claim that it exactly models by-value argument passing.