tl;dr: std::common_type_t<int&, int&>
is int
. What can we do to have int&
instead?
The reason for decaying behavior is explained in this question. The problem with such implementation is stripping away totally legitimate references (that is, the ones passed in by the user).
Indeed, we could write another metafunction going through the source types, figuring out their constness and "referenceness" and appropriately modifying the result of std::common_type
, but that seems just ugly. Can we do better?
For the curious ones, the motivation: I'm writing (yet another) visitor wrapper taking a set of lambdas and producing something that works with boost::variant
(or std::variant
for that matter). I want it to satisfy two requirements, among others:
Allow different lambdas return different but compatible types (like
Foo*
andBar*
forstruct Bar : Foo
).Allow returning non-const lvalue references from the lambdas.
To satisfy the former, I need to figure out the common type of the return values. To satisfy the latter, I need the common type to be a reference if all the original return types are references.